/*      */ package com.zimbra.cs.service.mail;
/*      */ 
/*      */ import com.google.common.base.Joiner;
/*      */ import com.google.common.base.Strings;
/*      */ import com.google.common.collect.Lists;
/*      */ import com.google.common.collect.Sets;
/*      */ import com.google.common.io.Closeables;
/*      */ import com.zimbra.common.account.Key.AccountBy;
/*      */ import com.zimbra.common.calendar.CalendarUtil;
/*      */ import com.zimbra.common.calendar.Geo;
/*      */ import com.zimbra.common.calendar.ICalTimeZone;
/*      */ import com.zimbra.common.calendar.ICalTimeZone.SimpleOnset;
/*      */ import com.zimbra.common.calendar.ParsedDateTime;
/*      */ import com.zimbra.common.calendar.ParsedDuration;
/*      */ import com.zimbra.common.calendar.TimeZoneMap;
/*      */ import com.zimbra.common.calendar.ZCalendar.ICalTok;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZParameter;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZProperty;
/*      */ import com.zimbra.common.localconfig.DebugConfig;
/*      */ import com.zimbra.common.localconfig.KnownKey;
/*      */ import com.zimbra.common.localconfig.LC;
/*      */ import com.zimbra.common.mailbox.Color;
/*      */ import com.zimbra.common.mailbox.ContactConstants;
/*      */ import com.zimbra.common.mime.ContentDisposition;
/*      */ import com.zimbra.common.mime.ContentType;
/*      */ import com.zimbra.common.mime.MimeDetect;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.soap.Element;
/*      */ import com.zimbra.common.soap.Element.ContainerException;
/*      */ import com.zimbra.common.soap.Element.Disposition;
/*      */ import com.zimbra.common.soap.Element.KeyValuePair;
/*      */ import com.zimbra.common.util.ArrayUtil;
/*      */ import com.zimbra.common.util.ByteUtil;
/*      */ import com.zimbra.common.util.DateUtil;
/*      */ import com.zimbra.common.util.HttpUtil;
/*      */ import com.zimbra.common.util.L10nUtil;
/*      */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.LogFactory;
/*      */ import com.zimbra.common.util.Pair;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.TruncatingWriter;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.common.zmime.ZInternetHeader;
/*      */ import com.zimbra.cs.account.AccessManager;
/*      */ import com.zimbra.cs.account.Account;
/*      */ import com.zimbra.cs.account.DataSource;
/*      */ import com.zimbra.cs.account.Domain;
/*      */ import com.zimbra.cs.account.GalContact;
/*      */ import com.zimbra.cs.account.IDNUtil;
/*      */ import com.zimbra.cs.account.NamedEntry;
/*      */ import com.zimbra.cs.account.Provisioning;
/*      */ import com.zimbra.cs.account.Server;
/*      */ import com.zimbra.cs.account.accesscontrol.GranteeType;
/*      */ import com.zimbra.cs.account.accesscontrol.Right;
/*      */ import com.zimbra.cs.account.accesscontrol.ZimbraACE;
/*      */ import com.zimbra.cs.fb.FreeBusy;
/*      */ import com.zimbra.cs.fb.FreeBusy.Interval;
/*      */ import com.zimbra.cs.gal.GalGroup.GroupInfo;
/*      */ import com.zimbra.cs.gal.GalGroupInfoProvider;
/*      */ import com.zimbra.cs.gal.GalGroupMembers.ContactDLMembers;
/*      */ import com.zimbra.cs.html.BrowserDefang;
/*      */ import com.zimbra.cs.html.DefangFactory;
/*      */ import com.zimbra.cs.httpclient.URLUtil;
/*      */ import com.zimbra.cs.index.SearchParams;
/*      */ import com.zimbra.cs.index.SearchParams.ExpandResults;
/*      */ import com.zimbra.cs.index.SortBy;
/*      */ import com.zimbra.cs.mailbox.ACL;
/*      */ import com.zimbra.cs.mailbox.ACL.Grant;
/*      */ import com.zimbra.cs.mailbox.Appointment;
/*      */ import com.zimbra.cs.mailbox.CalendarItem;
/*      */ import com.zimbra.cs.mailbox.CalendarItem.AlarmData;
/*      */ import com.zimbra.cs.mailbox.CalendarItem.Instance;
/*      */ import com.zimbra.cs.mailbox.CalendarItem.ReplyInfo;
/*      */ import com.zimbra.cs.mailbox.Chat;
/*      */ import com.zimbra.cs.mailbox.Comment;
/*      */ import com.zimbra.cs.mailbox.Contact;
/*      */ import com.zimbra.cs.mailbox.Contact.Attachment;
/*      */ import com.zimbra.cs.mailbox.ContactGroup;
/*      */ import com.zimbra.cs.mailbox.ContactGroup.Member;
/*      */ import com.zimbra.cs.mailbox.ContactGroup.Member.Type;
/*      */ import com.zimbra.cs.mailbox.Conversation;
/*      */ import com.zimbra.cs.mailbox.Document;
/*      */ import com.zimbra.cs.mailbox.Flag;
/*      */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*      */ import com.zimbra.cs.mailbox.Folder;
/*      */ import com.zimbra.cs.mailbox.Link;
/*      */ import com.zimbra.cs.mailbox.MailItem;
/*      */ import com.zimbra.cs.mailbox.MailItem.CustomMetadata;
/*      */ import com.zimbra.cs.mailbox.MailItem.Type;
/*      */ import com.zimbra.cs.mailbox.MailServiceException;
/*      */ import com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException;
/*      */ import com.zimbra.cs.mailbox.Mailbox;
/*      */ import com.zimbra.cs.mailbox.Message;
/*      */ import com.zimbra.cs.mailbox.Message.CalendarItemInfo;
/*      */ import com.zimbra.cs.mailbox.Mountpoint;
/*      */ import com.zimbra.cs.mailbox.Note;
/*      */ import com.zimbra.cs.mailbox.Note.Rectangle;
/*      */ import com.zimbra.cs.mailbox.OperationContext;
/*      */ import com.zimbra.cs.mailbox.OperationContextData;
/*      */ import com.zimbra.cs.mailbox.OperationContextData.GranteeNames;
/*      */ import com.zimbra.cs.mailbox.RetentionPolicyManager;
/*      */ import com.zimbra.cs.mailbox.SearchFolder;
/*      */ import com.zimbra.cs.mailbox.SenderList;
/*      */ import com.zimbra.cs.mailbox.SenderList.RefreshException;
/*      */ import com.zimbra.cs.mailbox.Tag;
/*      */ import com.zimbra.cs.mailbox.WikiItem;
/*      */ import com.zimbra.cs.mailbox.calendar.Alarm;
/*      */ import com.zimbra.cs.mailbox.calendar.Invite;
/*      */ import com.zimbra.cs.mailbox.calendar.InviteChanges;
/*      */ import com.zimbra.cs.mailbox.calendar.RecurId;
/*      */ import com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence;
/*      */ import com.zimbra.cs.mailbox.calendar.ZAttendee;
/*      */ import com.zimbra.cs.mailbox.calendar.ZOrganizer;
/*      */ import com.zimbra.cs.mailbox.util.TagUtil;
/*      */ import com.zimbra.cs.mime.MPartInfo;
/*      */ import com.zimbra.cs.mime.Mime;
/*      */ import com.zimbra.cs.mime.ParsedAddress;
/*      */ import com.zimbra.cs.mime.handler.TextEnrichedHandler;
/*      */ import com.zimbra.cs.service.UserServlet;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import com.zimbra.cs.service.util.ItemIdFormatter;
/*      */ import com.zimbra.soap.admin.type.DataSourceType;
/*      */ import com.zimbra.soap.mail.type.AlarmDataInfo;
/*      */ import com.zimbra.soap.mail.type.CalendarItemInfo;
/*      */ import com.zimbra.soap.mail.type.CalendarReply;
/*      */ import com.zimbra.soap.mail.type.Policy;
/*      */ import com.zimbra.soap.mail.type.Policy.Type;
/*      */ import com.zimbra.soap.mail.type.RetentionPolicy;
/*      */ import com.zimbra.soap.mail.type.XParam;
/*      */ import com.zimbra.soap.mail.type.XProp;
/*      */ import com.zimbra.soap.type.DataSource.ConnectionType;
/*      */ import com.zimbra.soap.type.WantRecipsSetting;
/*      */ import java.io.IOException;
/*      */ import java.io.InputStream;
/*      */ import java.io.Reader;
/*      */ import java.io.StringWriter;
/*      */ import java.io.UnsupportedEncodingException;
/*      */ import java.io.Writer;
/*      */ import java.util.Arrays;
/*      */ import java.util.Calendar;
/*      */ import java.util.Collection;
/*      */ import java.util.Collections;
/*      */ import java.util.Date;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.LinkedList;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ import javax.mail.MessagingException;
/*      */ import javax.mail.internet.InternetAddress;
/*      */ import javax.mail.internet.MimeMessage;
/*      */ import javax.mail.internet.MimePart;
/*      */ import javax.mail.internet.MimeUtility;
/*      */ import org.json.JSONException;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public final class ToXML
/*      */ {
/*  170 */   private static final Log LOG = LogFactory.getLog(ToXML.class);
/*      */   public static final int NOTIFY_FIELDS = -4194305;
/*      */   
/*  173 */   public static enum OutputParticipants { PUT_SENDERS(0), 
/*  174 */     PUT_RECIPIENTS(1), 
/*  175 */     PUT_BOTH(2);
/*      */     
/*      */     private int value;
/*      */     
/*  179 */     private OutputParticipants(int value) { this.value = value; }
/*      */     
/*      */     public int getIntValue()
/*      */     {
/*  183 */       return this.value;
/*      */     }
/*      */     
/*      */     public static OutputParticipants fromJaxb(WantRecipsSetting jaxb) {
/*  187 */       jaxb = WantRecipsSetting.usefulValue(jaxb);
/*  188 */       if (WantRecipsSetting.PUT_RECIPIENTS.equals(jaxb))
/*  189 */         return PUT_RECIPIENTS;
/*  190 */       if (WantRecipsSetting.PUT_BOTH.equals(jaxb)) {
/*  191 */         return PUT_BOTH;
/*      */       }
/*  193 */       return PUT_SENDERS;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeItem(Element parent, ItemIdFormatter ifmt, OperationContext octxt, MailItem item, int fields)
/*      */     throws ServiceException
/*      */   {
/*  206 */     if ((item instanceof Folder))
/*  207 */       return encodeFolder(parent, ifmt, octxt, (Folder)item, fields);
/*  208 */     if ((item instanceof Tag))
/*  209 */       return encodeTag(parent, ifmt, octxt, (Tag)item, fields);
/*  210 */     if ((item instanceof Note))
/*  211 */       return encodeNote(parent, ifmt, octxt, (Note)item, fields);
/*  212 */     if ((item instanceof Contact))
/*  213 */       return encodeContact(parent, ifmt, octxt, (Contact)item, false, null, fields);
/*  214 */     if ((item instanceof CalendarItem))
/*  215 */       return encodeCalendarItemSummary(parent, ifmt, octxt, (CalendarItem)item, fields, true);
/*  216 */     if ((item instanceof Conversation)) {
/*  217 */       return encodeConversationSummary(parent, ifmt, octxt, (Conversation)item, null, OutputParticipants.PUT_SENDERS, fields, false);
/*      */     }
/*  219 */     if ((item instanceof WikiItem))
/*  220 */       return encodeWiki(parent, ifmt, octxt, (WikiItem)item, fields);
/*  221 */     if ((item instanceof Document))
/*  222 */       return encodeDocument(parent, ifmt, octxt, (Document)item, fields);
/*  223 */     if ((item instanceof Message)) {
/*  224 */       OutputParticipants output = fields == -4194305 ? OutputParticipants.PUT_BOTH : OutputParticipants.PUT_SENDERS;
/*      */       
/*  226 */       return encodeMessageSummary(parent, ifmt, octxt, (Message)item, output, fields); }
/*  227 */     if ((item instanceof Comment)) {
/*  228 */       return encodeComment(parent, ifmt, octxt, (Comment)item, fields);
/*      */     }
/*  230 */     return null;
/*      */   }
/*      */   
/*      */   private static boolean needToOutput(int fields, int fieldMask)
/*      */   {
/*  235 */     return (fields & fieldMask) > 0;
/*      */   }
/*      */   
/*      */   public static boolean hasFullAccess(Mailbox mbox, OperationContext octxt) throws ServiceException {
/*  239 */     if ((octxt == null) || (!octxt.isDelegatedRequest(mbox))) {
/*  240 */       return true;
/*      */     }
/*  242 */     return AccessManager.getInstance().canAccessAccount(octxt.getAuthenticatedUser(), mbox.getAccount(), octxt.isUsingAdminPrivileges());
/*      */   }
/*      */   
/*      */   public static Element encodeMailbox(Element parent, OperationContext octxt, Mailbox mbox)
/*      */   {
/*  247 */     return encodeMailbox(parent, octxt, mbox, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeMailbox(Element parent, OperationContext octxt, Mailbox mbox, int fields) {
/*  251 */     Element elem = parent.addElement("mbx");
/*  252 */     if (octxt.isDelegatedRequest(mbox)) {
/*  253 */       elem.addAttribute("acct", mbox.getAccountId());
/*      */     }
/*  255 */     if (needToOutput(fields, 16)) {
/*  256 */       elem.addAttribute("s", mbox.getSize());
/*      */     }
/*  258 */     return elem;
/*      */   }
/*      */   
/*      */   public static Element encodeFolder(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Folder folder) throws ServiceException
/*      */   {
/*  263 */     return encodeFolder(parent, ifmt, octxt, folder, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeFolder(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Folder folder, int fields)
/*      */     throws ServiceException
/*      */   {
/*  269 */     return encodeFolder(parent, ifmt, octxt, folder, fields, false);
/*      */   }
/*      */   
/*      */   public static Element encodeFolder(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Folder folder, int fields, boolean exposeAclAccessKey)
/*      */     throws ServiceException
/*      */   {
/*  275 */     if ((folder instanceof SearchFolder))
/*  276 */       return encodeSearchFolder(parent, ifmt, (SearchFolder)folder, fields);
/*  277 */     if ((folder instanceof Mountpoint)) {
/*  278 */       return encodeMountpoint(parent, ifmt, octxt, (Mountpoint)folder, fields);
/*      */     }
/*  280 */     Element elem = parent.addElement("folder");
/*  281 */     encodeFolderCommon(elem, ifmt, folder, fields);
/*  282 */     if (needToOutput(fields, 16)) {
/*  283 */       int deleted = folder.getDeletedCount();
/*  284 */       elem.addAttribute("n", folder.getItemCount() - deleted);
/*  285 */       if (deleted > 0) {
/*  286 */         elem.addAttribute("i4n", folder.getItemCount());
/*      */       }
/*  288 */       elem.addAttribute("s", folder.getTotalSize());
/*  289 */       elem.addAttribute("i4ms", folder.getImapMODSEQ());
/*  290 */       elem.addAttribute("i4next", folder.getImapUIDNEXT());
/*      */     }
/*      */     
/*  293 */     if (needToOutput(fields, 262144)) {
/*  294 */       String url = folder.getUrl();
/*  295 */       if ((!url.isEmpty()) || (fields != -4194305))
/*      */       {
/*      */ 
/*      */ 
/*      */ 
/*  300 */         elem.addAttribute("url", HttpUtil.sanitizeURL(url));
/*      */       }
/*      */     }
/*      */     
/*  304 */     Mailbox mbox = folder.getMailbox();
/*  305 */     boolean remote = (octxt != null) && (octxt.isDelegatedRequest(mbox));
/*      */     
/*  307 */     boolean canAdminister = !remote;
/*  308 */     boolean canDelete = canAdminister;
/*  309 */     if (remote)
/*      */     {
/*  311 */       String perms = encodeEffectivePermissions(folder, octxt);
/*  312 */       elem.addAttribute("perm", perms);
/*  313 */       canAdminister = (perms != null) && (perms.indexOf('a') != -1);
/*      */       
/*      */ 
/*  316 */       canDelete = (canAdminister) || ((perms != null) && (perms.indexOf('d') != -1));
/*      */     }
/*      */     
/*  319 */     if (canAdminister)
/*      */     {
/*  321 */       if ((needToOutput(fields, 2097152)) && (
/*  322 */         (fields != -4194305) || (folder.isTagged(Flag.FlagInfo.NO_INHERIT)))) {
/*  323 */         encodeACL(octxt, elem, folder.getEffectiveACL(), exposeAclAccessKey);
/*      */       }
/*      */     }
/*      */     
/*  327 */     if ((canDelete) && 
/*  328 */       (needToOutput(fields, 33554432))) {
/*  329 */       RetentionPolicy rp = folder.getRetentionPolicy();
/*  330 */       if ((fields != -4194305) || (rp.isSet()))
/*      */       {
/*      */ 
/*  333 */         encodeRetentionPolicy(elem, RetentionPolicyManager.getInstance().getCompleteRetentionPolicy(folder.getAccount(), rp));
/*      */       }
/*      */     }
/*      */     
/*  337 */     return elem;
/*      */   }
/*      */   
/*      */   private static Element encodeRetentionPolicy(Element parent, RetentionPolicy policy) {
/*  341 */     Element retPol = parent.addElement("retentionPolicy");
/*  342 */     if (policy.isSet()) {
/*  343 */       Element keepEl = retPol.addElement("keep");
/*  344 */       encodePolicyList(keepEl, policy.getKeepPolicy());
/*  345 */       Element purgeEl = retPol.addElement("purge");
/*  346 */       encodePolicyList(purgeEl, policy.getPurgePolicy());
/*      */     }
/*  348 */     return retPol;
/*      */   }
/*      */   
/*      */   private static void encodePolicyList(Element parent, List<Policy> list) {
/*  352 */     if (list != null) {
/*  353 */       for (Policy p : list) {
/*  354 */         Element elem = parent.addElement("policy");
/*  355 */         elem.addAttribute("id", p.getId());
/*  356 */         elem.addAttribute("name", p.getName());
/*  357 */         elem.addAttribute("lifetime", p.getLifetime());
/*  358 */         elem.addAttribute("type", p.getType().toString());
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static String encodeEffectivePermissions(Folder folder, OperationContext octxt) {
/*      */     try {
/*  365 */       short perms = folder.getMailbox().getEffectivePermissions(octxt, folder.getId(), MailItem.Type.FOLDER);
/*  366 */       return ACL.rightsToString(perms);
/*      */     } catch (ServiceException e) {
/*  368 */       LOG.warn("ignoring exception while fetching effective permissions for folder %d", Integer.valueOf(folder.getId()), e); }
/*  369 */     return null;
/*      */   }
/*      */   
/*      */ 
/*      */   public static Element encodeACL(OperationContext octxt, Element parent, ACL acl, boolean exposeAclAccessKey)
/*      */   {
/*  375 */     Element eACL = parent.addUniqueElement("acl");
/*  376 */     if (acl == null) {
/*  377 */       return eACL;
/*      */     }
/*      */     
/*  380 */     if (acl.getInternalGrantExpiry() != 0L) {
/*  381 */       eACL.addAttribute("internalGrantExpiry", acl.getInternalGrantExpiry());
/*      */     }
/*  383 */     if (acl.getGuestGrantExpiry() != 0L) {
/*  384 */       eACL.addAttribute("guestGrantExpiry", acl.getGuestGrantExpiry());
/*      */     }
/*      */     
/*  387 */     boolean needDispName = OperationContextData.getNeedGranteeName(octxt);
/*  388 */     for (ACL.Grant grant : acl.getGrants()) {
/*  389 */       String name = null;
/*  390 */       byte granteeType = grant.getGranteeType();
/*      */       
/*  392 */       if (needDispName)
/*      */       {
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  399 */         name = grant.getGranteeName();
/*  400 */         if (name == null)
/*      */         {
/*  402 */           OperationContextData.GranteeNames granteeNames = OperationContextData.getGranteeNames(octxt);
/*  403 */           if (granteeNames != null) {
/*  404 */             name = granteeNames.getNameById(grant.getGranteeId(), granteeType);
/*      */           }
/*      */           
/*      */ 
/*  408 */           if (name == null) {
/*  409 */             NamedEntry nentry = FolderAction.lookupGranteeByZimbraId(grant.getGranteeId(), granteeType);
/*  410 */             if (nentry != null) {
/*  411 */               name = nentry.getName();
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*  417 */       Element eGrant = eACL.addElement("grant");
/*  418 */       eGrant.addAttribute("zid", grant.getGranteeId()).addAttribute("gt", ACL.typeToString(granteeType)).addAttribute("perm", ACL.rightsToString(grant.getGrantedRights()));
/*      */       
/*      */ 
/*  421 */       if (grant.getExpiry() != 0L) {
/*  422 */         eGrant.addAttribute("expiry", grant.getExpiry());
/*      */       }
/*      */       
/*  425 */       if (needDispName)
/*      */       {
/*      */ 
/*  428 */         if (OperationContextData.GranteeNames.INVALID_GRANT == name) {
/*  429 */           eGrant.addAttribute("invalid", true);
/*  430 */           eGrant.addAttribute("d", "");
/*      */         } else {
/*  432 */           eGrant.addAttribute("d", name);
/*      */         }
/*      */       }
/*      */       
/*  436 */       if (granteeType == 8) {
/*  437 */         if (exposeAclAccessKey) {
/*  438 */           eGrant.addAttribute("key", grant.getPassword());
/*      */         }
/*      */       } else {
/*  441 */         eGrant.addAttribute("pw", grant.getPassword());
/*      */       }
/*      */     }
/*  444 */     return eACL;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeACE(Element parent, ZimbraACE ace)
/*      */   {
/*  452 */     Element eACE = parent.addElement("ace").addAttribute("zid", ace.getGrantee()).addAttribute("gt", ace.getGranteeType().getCode()).addAttribute("right", ace.getRight().getName()).addAttribute("d", ace.getGranteeDisplayName());
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  458 */     if (ace.getGranteeType() == GranteeType.GT_KEY) {
/*  459 */       eACE.addAttribute("key", ace.getSecret());
/*  460 */     } else if (ace.getGranteeType() == GranteeType.GT_GUEST) {
/*  461 */       eACE.addAttribute("pw", ace.getSecret());
/*      */     }
/*  463 */     if (ace.deny()) {
/*  464 */       eACE.addAttribute("deny", ace.deny());
/*      */     }
/*  466 */     return eACE;
/*      */   }
/*      */   
/*      */   private static Element encodeFolderCommon(Element elem, ItemIdFormatter ifmt, Folder folder, int fields) throws ServiceException
/*      */   {
/*  471 */     int folderId = folder.getId();
/*  472 */     elem.addAttribute("id", ifmt.formatItemId(folder));
/*  473 */     elem.addAttribute("uuid", folder.getUuid());
/*      */     
/*  475 */     if (folderId != 11) {
/*  476 */       boolean encodedPath = false;
/*  477 */       if (needToOutput(fields, 4096)) {
/*  478 */         String name = folder.getName();
/*  479 */         if (!Strings.isNullOrEmpty(name)) {
/*  480 */           elem.addAttribute("name", name);
/*      */         }
/*  482 */         elem.addAttribute("absFolderPath", folder.getPath());
/*  483 */         encodedPath = true;
/*      */       }
/*  485 */       if (needToOutput(fields, 256)) {
/*  486 */         elem.addAttribute("l", ifmt.formatItemId(new ItemId(folder.getMailbox(), folder.getFolderId())));
/*  487 */         elem.addAttribute("luuid", folder.getFolderUuid());
/*  488 */         if (!encodedPath) {
/*  489 */           elem.addAttribute("absFolderPath", folder.getPath());
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  494 */     if (needToOutput(fields, 4)) {
/*  495 */       String flags = folder.getMailbox().getItemFlagString(folder);
/*  496 */       if ((fields != -4194305) || (!flags.isEmpty())) {
/*  497 */         elem.addAttribute("f", flags);
/*      */       }
/*      */     }
/*  500 */     encodeColor(elem, folder, fields);
/*  501 */     if (needToOutput(fields, 1)) {
/*  502 */       int unread = folder.getUnreadCount();
/*  503 */       if ((unread > 0) || (fields != -4194305)) {
/*  504 */         int deletedUnread = folder.getDeletedUnreadCount();
/*  505 */         elem.addAttribute("u", unread - deletedUnread);
/*  506 */         if (deletedUnread > 0) {
/*  507 */           elem.addAttribute("i4u", unread);
/*      */         }
/*      */       }
/*      */     }
/*  511 */     if (needToOutput(fields, 1048576)) {
/*  512 */       MailItem.Type view = folder.getDefaultView();
/*  513 */       if (view != MailItem.Type.UNKNOWN) {
/*  514 */         elem.addAttribute("view", view.toString());
/*      */       }
/*      */     }
/*  517 */     if (needToOutput(fields, 65536)) {
/*  518 */       elem.addAttribute("rev", folder.getSavedSequence());
/*      */       
/*      */ 
/*  521 */       elem.addAttribute("ms", folder.getModifiedSequence());
/*      */     }
/*  523 */     if (needToOutput(fields, 4194304)) {
/*  524 */       elem.addAttribute("md", folder.getChangeDate() / 1000L);
/*  525 */       elem.addAttribute("ms", folder.getModifiedSequence());
/*  526 */       elem.addAttribute("mdver", folder.getMetadataVersion());
/*      */     }
/*  528 */     if (needToOutput(fields, 524288)) {
/*  529 */       encodeAllCustomMetadata(elem, folder, fields);
/*  530 */       elem.addAttribute("webOfflineSyncDays", folder.getWebOfflineSyncDays());
/*      */     }
/*  532 */     if (needToOutput(fields, 67108864)) {
/*  533 */       elem.addAttribute("activesyncdisabled", folder.isActiveSyncDisabled());
/*      */     }
/*  535 */     return elem;
/*      */   }
/*      */   
/*      */   public static Element encodeSearchFolder(Element parent, ItemIdFormatter ifmt, SearchFolder search) throws ServiceException
/*      */   {
/*  540 */     return encodeSearchFolder(parent, ifmt, search, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeSearchFolder(Element parent, ItemIdFormatter ifmt, SearchFolder search, int fields) throws ServiceException
/*      */   {
/*  545 */     Element elem = parent.addElement("search");
/*  546 */     encodeFolderCommon(elem, ifmt, search, fields);
/*  547 */     if (needToOutput(fields, 32768)) {
/*  548 */       elem.addAttribute("query", search.getQuery());
/*  549 */       elem.addAttribute("sortBy", search.getSortField());
/*  550 */       elem.addAttribute("types", search.getReturnTypes());
/*      */     }
/*  552 */     return elem;
/*      */   }
/*      */   
/*      */   public static Element encodeMountpoint(Element parent, ItemIdFormatter ifmt, OperationContext octx, Mountpoint mpt) throws ServiceException
/*      */   {
/*  557 */     return encodeMountpoint(parent, ifmt, octx, mpt, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeMountpoint(Element parent, ItemIdFormatter ifmt, OperationContext octx, Mountpoint mpt, int fields)
/*      */     throws ServiceException
/*      */   {
/*  563 */     Element el = parent.addElement("link");
/*  564 */     encodeFolderCommon(el, ifmt, mpt, fields);
/*  565 */     if (needToOutput(fields, 65536)) {
/*  566 */       el.addAttribute("zid", mpt.getOwnerId());
/*  567 */       el.addAttribute("rid", mpt.getRemoteId());
/*  568 */       el.addAttribute("ruuid", mpt.getRemoteUuid());
/*  569 */       NamedEntry nentry = FolderAction.lookupGranteeByZimbraId(mpt.getOwnerId(), (byte)1);
/*  570 */       el.addAttribute("owner", nentry == null ? null : nentry.getName());
/*  571 */       if (mpt.getDefaultView() != MailItem.Type.UNKNOWN) {
/*  572 */         el.addAttribute("view", mpt.getDefaultView().toString());
/*      */       }
/*      */     }
/*  575 */     if (needToOutput(fields, 16777216)) {
/*  576 */       el.addAttribute("reminder", false);
/*      */     }
/*  578 */     return el;
/*      */   }
/*      */   
/*      */   private static String getRestUrl(String ownerName, String folderPath) {
/*  582 */     if ((ownerName == null) || (folderPath == null)) {
/*  583 */       return null;
/*      */     }
/*  585 */     Provisioning prov = Provisioning.getInstance();
/*      */     try
/*      */     {
/*  588 */       Account targetAccount = prov.get(Key.AccountBy.name, ownerName);
/*  589 */       if (targetAccount == null)
/*      */       {
/*  591 */         return null;
/*      */       }
/*  593 */       Server targetServer = prov.getServer(targetAccount);
/*  594 */       Domain targetDomain = prov.getDomain(targetAccount);
/*  595 */       return URLUtil.getPublicURLForDomain(targetServer, targetDomain, "/home" + HttpUtil.urlEscape(new StringBuilder().append(UserServlet.getAccountPath(targetAccount)).append(folderPath).toString()), true);
/*      */     }
/*      */     catch (ServiceException e) {
/*  598 */       ZimbraLog.soap.warn("unable to create rest url for mountpoint", e); }
/*  599 */     return null;
/*      */   }
/*      */   
/*      */ 
/*      */   public static void transferMountpointContents(Element elem, Element mptTarget)
/*      */   {
/*  605 */     transferLongAttribute(elem, mptTarget, "u");
/*  606 */     transferLongAttribute(elem, mptTarget, "n");
/*  607 */     transferLongAttribute(elem, mptTarget, "s");
/*  608 */     elem.addAttribute("oname", mptTarget.getAttribute("name", null));
/*  609 */     String ownerName = elem.getAttribute("owner", null);
/*  610 */     String ownerFolderPath = mptTarget.getAttribute("absFolderPath", null);
/*      */     
/*  612 */     elem.addAttribute("rest", getRestUrl(ownerName, ownerFolderPath));
/*  613 */     elem.addAttribute("url", mptTarget.getAttribute("url", null));
/*  614 */     elem.addAttribute("perm", mptTarget.getAttribute("perm", null));
/*  615 */     if (mptTarget.getAttribute("f", "").indexOf("u") != -1) {
/*  616 */       elem.addAttribute("f", "u" + elem.getAttribute("f", "").replace("u", ""));
/*      */     }
/*      */     
/*  619 */     for (Element child : mptTarget.listElements()) {
/*  620 */       String name = child.getName();
/*      */       
/*  622 */       if ((name.equals("folder")) || (name.equals("search")) || (name.equals("link")) || (name.equals("retentionPolicy")) || (name.equals("meta")))
/*      */       {
/*      */ 
/*  625 */         elem.addNonUniqueElement(child.clone());
/*      */       } else {
/*  627 */         elem.addUniqueElement(child.clone());
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static void transferLongAttribute(Element to, Element from, String attrName) {
/*      */     try {
/*  634 */       long remote = from.getAttributeLong(attrName, -1L);
/*  635 */       if (remote >= 0L) {
/*  636 */         to.addAttribute(attrName, remote);
/*      */       }
/*      */     } catch (ServiceException e) {
/*  639 */       ZimbraLog.session.warn("exception reading long attr from remote folder: %s", attrName, e);
/*      */     } catch (Element.ContainerException e) {
/*  641 */       ZimbraLog.session.warn("exception adding remote folder attr to serialized mountpoint: %s", attrName, e);
/*      */     }
/*      */   }
/*      */   
/*      */   public static Element encodeRestUrl(Element el, MailItem item) {
/*      */     try {
/*  647 */       return el.addAttribute("rest", UserServlet.getRestUrl(item));
/*      */     } catch (ServiceException e) {
/*  649 */       LOG.error("cannot generate REST url", e); }
/*  650 */     return el;
/*      */   }
/*      */   
/*      */   public static void recordItemTags(Element elem, MailItem item, OperationContext octxt) throws ServiceException
/*      */   {
/*  655 */     recordItemTags(elem, item, octxt, -4194305);
/*      */   }
/*      */   
/*      */   public static void recordItemTags(Element elem, MailItem item, OperationContext octxt, int fields) throws ServiceException {
/*  659 */     if (needToOutput(fields, 5)) {
/*  660 */       String flags = item.getFlagString();
/*  661 */       if ((fields != -4194305) || (!flags.isEmpty())) {
/*  662 */         elem.addAttribute("f", flags);
/*      */       }
/*      */     }
/*  665 */     if (needToOutput(fields, 2)) {
/*  666 */       String[] tags = item.getTags();
/*  667 */       if ((!ArrayUtil.isEmpty(tags)) || (fields != -4194305)) {
/*  668 */         elem.addAttribute("tn", TagUtil.encodeTags(tags));
/*  669 */         if (hasFullAccess(item.getMailbox(), octxt)) {
/*  670 */           elem.addAttribute("t", TagUtil.getTagIdString(item));
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static void encodeAllCustomMetadata(Element elem, MailItem item, int fields) {
/*  677 */     List<String> sections = item.getCustomDataSections();
/*  678 */     if ((sections == null) || (sections.isEmpty()))
/*      */     {
/*  680 */       if (fields != -4194305) {
/*  681 */         elem.addElement("meta");
/*      */       }
/*  683 */       return;
/*      */     }
/*      */     
/*  686 */     for (String section : sections) {
/*      */       try {
/*  688 */         encodeCustomMetadata(elem, item.getCustomData(section));
/*      */       } catch (ServiceException e) {
/*  690 */         ZimbraLog.soap.warn("could not deserialize custom metadata; skipping (section '%s', item %s)", new Object[] { section, new ItemId(item) });
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static Element encodeCustomMetadata(Element elem, MailItem.CustomMetadata custom)
/*      */   {
/*  697 */     if (custom == null) {
/*  698 */       return null;
/*      */     }
/*  700 */     Element serialized = elem.addElement("meta");
/*  701 */     serialized.addAttribute("section", custom.getSectionKey());
/*  702 */     for (Map.Entry<String, String> entry : custom.entrySet()) {
/*  703 */       serialized.addKeyValuePair((String)entry.getKey(), (String)entry.getValue());
/*      */     }
/*  705 */     return serialized;
/*      */   }
/*      */   
/*      */   public static Element encodeContact(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Contact contact, boolean summary, Collection<String> attrFilter)
/*      */     throws ServiceException
/*      */   {
/*  711 */     return encodeContact(parent, ifmt, octxt, contact, summary, attrFilter, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeContact(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Contact contact, boolean summary, Collection<String> attrFilter, int fields)
/*      */     throws ServiceException
/*      */   {
/*  717 */     return encodeContact(parent, ifmt, octxt, contact, null, null, summary, attrFilter, fields, null, false, 0L);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeContact(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Contact contact, ContactGroup contactGroup, Collection<String> memberAttrFilter, boolean summary, Collection<String> attrFilter, int fields, String migratedDlist, boolean returnHiddenAttrs, long maxMembers)
/*      */     throws ServiceException
/*      */   {
/*  726 */     Element el = parent.addElement("cn");
/*  727 */     el.addAttribute("id", ifmt.formatItemId(contact));
/*  728 */     if (needToOutput(fields, 256)) {
/*  729 */       el.addAttribute("l", ifmt.formatItemId(new ItemId(contact.getMailbox().getAccountId(), contact.getFolderId())));
/*      */     }
/*      */     
/*  732 */     recordItemTags(el, contact, octxt, fields);
/*  733 */     if (needToOutput(fields, 4194304)) {
/*  734 */       el.addAttribute("md", contact.getChangeDate() / 1000L);
/*  735 */       el.addAttribute("ms", contact.getModifiedSequence());
/*  736 */       el.addAttribute("d", contact.getDate());
/*  737 */       el.addAttribute("rev", contact.getSavedSequence());
/*  738 */     } else if (needToOutput(fields, 65536)) {
/*  739 */       el.addAttribute("d", contact.getDate());
/*  740 */       el.addAttribute("rev", contact.getSavedSequence());
/*      */     }
/*  742 */     if (needToOutput(fields, 524288)) {
/*  743 */       encodeAllCustomMetadata(el, contact, fields);
/*      */     }
/*  745 */     if (!needToOutput(fields, 65536)) {
/*  746 */       if (summary) {
/*      */         try {
/*  748 */           el.addAttribute("fileAsStr", contact.getFileAsString());
/*      */         }
/*      */         catch (ServiceException e) {}
/*  751 */         el.addAttribute(ContactConstants.A_email, contact.get(ContactConstants.A_email));
/*  752 */         el.addAttribute(ContactConstants.A_email2, contact.get(ContactConstants.A_email2));
/*  753 */         el.addAttribute(ContactConstants.A_email3, contact.get(ContactConstants.A_email3));
/*      */         
/*  755 */         String type = contact.get(ContactConstants.A_type);
/*  756 */         el.addAttribute(ContactConstants.A_type, type);
/*      */         
/*      */ 
/*  759 */         el.addAttribute("md", contact.getChangeDate() / 1000L);
/*      */       }
/*      */       
/*      */ 
/*  763 */       return el;
/*      */     }
/*      */     try
/*      */     {
/*  767 */       el.addAttribute("fileAsStr", contact.getFileAsString());
/*      */     }
/*      */     catch (ServiceException e) {}
/*      */     
/*  771 */     List<Contact.Attachment> attachments = contact.getAttachments();
/*      */     
/*      */ 
/*      */ 
/*  775 */     boolean encodeContactGroupMembersBasic = (contactGroup == null) && (migratedDlist == null);
/*      */     Iterator i$;
/*  777 */     String name; if (attrFilter != null) {
/*  778 */       for (i$ = attrFilter.iterator(); i$.hasNext();) { name = (String)i$.next();
/*      */         
/*      */ 
/*  781 */         String value = contact.get(name);
/*  782 */         if (!Strings.isNullOrEmpty(value)) {
/*  783 */           encodeContactAttr(el, name, value, contact, encodeContactGroupMembersBasic);
/*  784 */         } else if (attachments != null) {
/*  785 */           for (Contact.Attachment attach : attachments) {
/*  786 */             if (attach.getName().equals(name)) {
/*  787 */               encodeContactAttachment(el, attach);
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/*      */     } else {
/*  793 */       Map<String, String> contactFields = returnHiddenAttrs ? contact.getAllFields() : contact.getFields();
/*      */       
/*  795 */       for (Map.Entry<String, String> me : contactFields.entrySet()) {
/*  796 */         String name = (String)me.getKey();
/*  797 */         String value = (String)me.getValue();
/*      */         
/*      */ 
/*      */ 
/*  801 */         if ((ContactConstants.A_member.equals(name)) && (maxMembers != 0L))
/*      */         {
/*      */ 
/*  804 */           GalGroupMembers.ContactDLMembers dlMembers = new GalGroupMembers.ContactDLMembers(contact);
/*  805 */           if (dlMembers.getTotal() > maxMembers) {
/*  806 */             el.addAttribute("tooManyMembers", true);
/*  807 */             continue;
/*      */           }
/*      */         }
/*      */         
/*  811 */         if ((name != null) && (!name.trim().isEmpty()) && (!Strings.isNullOrEmpty(value))) {
/*  812 */           encodeContactAttr(el, name, value, contact, encodeContactGroupMembersBasic);
/*      */         }
/*      */       }
/*  815 */       if (attachments != null) {
/*  816 */         for (Contact.Attachment attach : attachments) {
/*  817 */           encodeContactAttachment(el, attach);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  822 */     if (migratedDlist != null) {
/*  823 */       encodeContactAttr(el, ContactConstants.A_dlist, migratedDlist, contact, false);
/*  824 */     } else if (contactGroup != null) {
/*  825 */       encodeContactGroup(el, contactGroup, memberAttrFilter, ifmt, octxt, summary, fields);
/*      */     }
/*      */     
/*  828 */     return el;
/*      */   }
/*      */   
/*      */   private static void encodeContactAttr(Element elem, String name, String value, Contact contact, boolean encodeContactGroupMembers)
/*      */   {
/*  833 */     if (Contact.isMultiValueAttr(value)) {
/*      */       try {
/*  835 */         for (String v : Contact.parseMultiValueAttr(value)) {
/*  836 */           elem.addKeyValuePair(name, v);
/*      */         }
/*  838 */         return;
/*      */       } catch (JSONException e) {}
/*  840 */     } else if (ContactConstants.A_groupMember.equals(name)) {
/*  841 */       if (encodeContactGroupMembers) {
/*      */         try {
/*  843 */           ContactGroup contactGroup = ContactGroup.init(contact, false);
/*  844 */           if (contactGroup != null) {
/*  845 */             for (ContactGroup.Member member : contactGroup.getMembers(true)) {
/*  846 */               Element eMember = elem.addElement("m");
/*  847 */               encodeContactGroupMemberBasic(eMember, member);
/*      */             }
/*      */           }
/*      */         } catch (ServiceException e) {
/*  851 */           ZimbraLog.contact.warn("unable to init contact group", e);
/*      */         }
/*      */       }
/*      */     } else {
/*  855 */       elem.addKeyValuePair(name, value);
/*      */     }
/*      */   }
/*      */   
/*      */   private static void encodeContactGroupMemberBasic(Element eMember, ContactGroup.Member member) {
/*  860 */     eMember.addAttribute("type", member.getType().getSoapEncoded());
/*  861 */     eMember.addAttribute("value", member.getValue());
/*      */   }
/*      */   
/*      */ 
/*      */   private static void encodeContactGroup(Element elem, ContactGroup contactGroup, Collection<String> memberAttrFilter, ItemIdFormatter ifmt, OperationContext octxt, boolean summary, int fields)
/*      */     throws ServiceException
/*      */   {
/*  868 */     for (ContactGroup.Member member : contactGroup.getMembers(true)) {
/*  869 */       Element eMember = elem.addElement("m");
/*  870 */       encodeContactGroupMemberBasic(eMember, member);
/*  871 */       Object derefedMember = member.getDerefedObj();
/*  872 */       if ((derefedMember != null) && 
/*  873 */         (!(derefedMember instanceof String)))
/*      */       {
/*  875 */         if ((derefedMember instanceof Contact))
/*      */         {
/*      */ 
/*  878 */           encodeContact(eMember, ifmt, octxt, (Contact)derefedMember, summary, memberAttrFilter, fields);
/*  879 */         } else if ((derefedMember instanceof GalContact)) {
/*  880 */           encodeGalContact(eMember, (GalContact)derefedMember, memberAttrFilter);
/*  881 */         } else if ((derefedMember instanceof Element))
/*      */         {
/*  883 */           Element eContact = (Element)derefedMember;
/*  884 */           if (memberAttrFilter != null) {
/*  885 */             for (Element eAttr : eContact.listElements()) {
/*  886 */               String name = eAttr.getAttribute("n", null);
/*  887 */               if (!memberAttrFilter.contains(name)) {
/*  888 */                 eAttr.detach();
/*      */               }
/*      */             }
/*      */           }
/*  892 */           eMember.addElement(eContact);
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static void encodeContactAttachment(Element elem, Contact.Attachment attach) {
/*  899 */     Element.KeyValuePair kvp = elem.addKeyValuePair(attach.getName(), null);
/*  900 */     kvp.addAttribute("part", attach.getPartName()).addAttribute("ct", attach.getContentType());
/*      */     
/*  902 */     kvp.addAttribute("s", attach.getSize()).addAttribute("filename", attach.getFilename());
/*      */   }
/*      */   
/*      */   public static Element encodeNote(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Note note) throws ServiceException
/*      */   {
/*  907 */     return encodeNote(parent, ifmt, octxt, note, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeNote(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Note note, int fields) throws ServiceException {
/*  911 */     Element el = parent.addElement("note");
/*  912 */     el.addAttribute("id", ifmt.formatItemId(note));
/*  913 */     if ((needToOutput(fields, 65536)) && (note.getSavedSequence() != 0)) {
/*  914 */       el.addAttribute("rev", note.getSavedSequence());
/*      */     }
/*  916 */     if (needToOutput(fields, 256)) {
/*  917 */       el.addAttribute("l", ifmt.formatItemId(new ItemId(note.getMailbox().getAccountId(), note.getFolderId())));
/*      */     }
/*      */     
/*  920 */     if (needToOutput(fields, 32)) {
/*  921 */       el.addAttribute("d", note.getDate());
/*      */     }
/*  923 */     recordItemTags(el, note, octxt, fields);
/*  924 */     if (needToOutput(fields, 16384)) {
/*  925 */       el.addAttribute("pos", note.getBounds().toString());
/*      */     }
/*  927 */     encodeColor(el, note, fields);
/*  928 */     if (needToOutput(fields, 65536)) {
/*  929 */       el.addAttribute("content", note.getText(), Element.Disposition.CONTENT);
/*      */     }
/*  931 */     if (needToOutput(fields, 4194304)) {
/*  932 */       el.addAttribute("md", note.getChangeDate() / 1000L);
/*  933 */       el.addAttribute("ms", note.getModifiedSequence());
/*      */     }
/*  935 */     if (needToOutput(fields, 524288)) {
/*  936 */       encodeAllCustomMetadata(el, note, fields);
/*      */     }
/*  938 */     return el;
/*      */   }
/*      */   
/*      */   public static Element encodeTag(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Tag tag) throws ServiceException
/*      */   {
/*  943 */     return encodeTag(parent, ifmt, octxt, tag, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeTag(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Tag tag, int fields) throws ServiceException
/*      */   {
/*  948 */     Element el = parent.addElement("tag");
/*      */     
/*  950 */     el.addAttribute("id", ifmt.formatItemId(tag));
/*      */     
/*  952 */     el.addAttribute("name", tag.getName());
/*  953 */     encodeColor(el, tag, fields);
/*  954 */     if (needToOutput(fields, 1)) {
/*  955 */       int unreadCount = tag.getUnreadCount();
/*  956 */       if ((unreadCount > 0) || (fields != -4194305)) {
/*  957 */         el.addAttribute("u", unreadCount);
/*      */       }
/*      */     }
/*  960 */     if (needToOutput(fields, 16)) {
/*  961 */       long num = tag.getItemCount();
/*  962 */       if ((num > 0L) || (fields != -4194305)) {
/*  963 */         el.addAttribute("n", num);
/*      */       }
/*      */     }
/*  966 */     if (needToOutput(fields, 4194304)) {
/*  967 */       el.addAttribute("d", tag.getDate());
/*  968 */       el.addAttribute("rev", tag.getSavedSequence());
/*  969 */       el.addAttribute("md", tag.getChangeDate() / 1000L);
/*  970 */       el.addAttribute("ms", tag.getModifiedSequence());
/*      */     }
/*  972 */     if (needToOutput(fields, 524288)) {
/*  973 */       encodeAllCustomMetadata(el, tag, fields);
/*      */     }
/*  975 */     boolean remote = (octxt != null) && (octxt.isDelegatedRequest(tag.getMailbox()));
/*  976 */     boolean canAdminister = !remote;
/*  977 */     if ((canAdminister) && 
/*  978 */       (needToOutput(fields, 33554432))) {
/*  979 */       RetentionPolicy rp = tag.getRetentionPolicy();
/*  980 */       if ((fields != -4194305) || (rp.isSet()))
/*      */       {
/*      */ 
/*  983 */         encodeRetentionPolicy(el, RetentionPolicyManager.getInstance().getCompleteRetentionPolicy(tag.getAccount(), rp));
/*      */       }
/*      */     }
/*      */     
/*  987 */     return el;
/*      */   }
/*      */   
/*      */   public static Element encodeColor(Element el, MailItem item, int fields) {
/*  991 */     if (needToOutput(fields, 8192)) {
/*  992 */       Color color = item.getRgbColor();
/*  993 */       if (color.hasMapping()) {
/*  994 */         byte mappedColor = color.getMappedColor();
/*  995 */         if ((mappedColor != 0) || (fields != -4194305)) {
/*  996 */           el.addAttribute("color", mappedColor);
/*      */         }
/*      */       } else {
/*  999 */         el.addAttribute("rgb", color.toString());
/*      */       }
/*      */     }
/* 1002 */     return el;
/*      */   }
/*      */   
/*      */   public static Element encodeConversation(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, SearchParams params) throws ServiceException
/*      */   {
/* 1007 */     Mailbox mbox = conv.getMailbox();
/* 1008 */     List<Message> msgs = mbox.getMessagesByConversation(octxt, conv.getId(), SortBy.DATE_ASC, -1);
/* 1009 */     return encodeConversation(parent, ifmt, octxt, conv, msgs, params);
/*      */   }
/*      */   
/*      */   public static Element encodeConversation(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, List<Message> msgs, SearchParams params) throws ServiceException
/*      */   {
/* 1014 */     int fields = -4194305;
/* 1015 */     Element c = encodeConversationSummary(parent, ifmt, octxt, conv, msgs, null, OutputParticipants.PUT_BOTH, fields, true);
/* 1016 */     if (msgs.isEmpty()) {
/* 1017 */       return c;
/*      */     }
/* 1019 */     c.addAttribute("su", ((Message)msgs.get(0)).getSubject(), Element.Disposition.CONTENT);
/*      */     
/* 1021 */     SearchParams.ExpandResults expand = params.getInlineRule();
/* 1022 */     for (Message msg : msgs) {
/* 1023 */       if (!msg.isTagged(Flag.FlagInfo.DELETED))
/*      */       {
/*      */ 
/* 1026 */         if ((expand == SearchParams.ExpandResults.FIRST) || (expand == SearchParams.ExpandResults.ALL) || (expand.matches(msg))) {
/* 1027 */           encodeMessageAsMP(c, ifmt, octxt, msg, null, params.getMaxInlinedLength(), params.getWantHtml(), params.getNeuterImages(), params.getInlinedHeaders(), true, params.getWantExpandGroupInfo(), LC.mime_encode_missing_blob.booleanValue());
/*      */           
/*      */ 
/* 1030 */           if (expand == SearchParams.ExpandResults.FIRST) {
/* 1031 */             expand = SearchParams.ExpandResults.NONE;
/*      */           }
/*      */         } else {
/* 1034 */           Element m = c.addElement("m");
/* 1035 */           m.addAttribute("id", ifmt.formatItemId(msg));
/* 1036 */           m.addAttribute("d", msg.getDate());
/* 1037 */           m.addAttribute("s", msg.getSize());
/* 1038 */           m.addAttribute("l", ifmt.formatItemId(new ItemId(msg.getMailbox().getAccountId(), msg.getFolderId())));
/*      */           
/* 1040 */           recordItemTags(m, msg, octxt, fields);
/* 1041 */           m.addAttribute("fr", msg.getFragment(), Element.Disposition.CONTENT);
/* 1042 */           encodeEmail(m, msg.getSender(), EmailType.FROM);
/*      */         } }
/*      */     }
/* 1045 */     return c;
/*      */   }
/*      */   
/*      */   private static class ToRecipsList
/*      */   {
/*      */     private static final int MAX_COUNT = 8;
/* 1051 */     private final List<ParsedAddress> aggregatedRecipients = Lists.newArrayListWithCapacity(8);
/* 1052 */     private boolean mIsElided = false;
/*      */     
/*      */ 
/*      */     public ToRecipsList add(Message msg)
/*      */     {
/* 1057 */       InternetAddress[] toRecips = Mime.parseAddressHeader(msg.getRecipients());
/* 1058 */       String sender = msg.getSender();
/* 1059 */       if ((sender == null) || (sender.trim().equals(""))) {
/* 1060 */         return this;
/*      */       }
/*      */       
/* 1063 */       for (InternetAddress ia : toRecips) {
/* 1064 */         ParsedAddress pa = new ParsedAddress(ia);
/* 1065 */         this.aggregatedRecipients.remove(pa);
/* 1066 */         this.aggregatedRecipients.add(0, pa);
/*      */       }
/* 1068 */       while (this.aggregatedRecipients.size() > 8) {
/* 1069 */         this.aggregatedRecipients.remove(8);
/* 1070 */         this.mIsElided = true;
/*      */       }
/* 1072 */       return this;
/*      */     }
/*      */     
/* 1075 */     public boolean isElided() { return this.mIsElided; }
/*      */     
/*      */     public List<ParsedAddress> getLastAddresses() {
/* 1078 */       if ((this.aggregatedRecipients == null) || (this.aggregatedRecipients.isEmpty()))
/* 1079 */         return Collections.emptyList();
/* 1080 */       List<ParsedAddress> addrs = Lists.newArrayList(this.aggregatedRecipients);
/* 1081 */       if (addrs.size() > 1) {
/* 1082 */         Collections.reverse(addrs);
/*      */       }
/* 1084 */       return addrs;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeConversationSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, int fields)
/*      */     throws ServiceException
/*      */   {
/* 1094 */     return encodeConversationSummary(parent, ifmt, octxt, conv, null, OutputParticipants.PUT_SENDERS, fields, true);
/*      */   }
/*      */   
/*      */   public static Element encodeConversationSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, Message msgHit, OutputParticipants output)
/*      */     throws ServiceException
/*      */   {
/* 1100 */     return encodeConversationSummary(parent, ifmt, octxt, conv, msgHit, output, -4194305, true);
/*      */   }
/*      */   
/*      */   private static Element encodeConversationSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, Message msgHit, OutputParticipants output, int fields, boolean alwaysSerialize)
/*      */     throws ServiceException
/*      */   {
/* 1106 */     List<Message> msgs = null;
/* 1107 */     Mailbox mbox = conv.getMailbox();
/*      */     
/*      */ 
/* 1110 */     boolean isDelegatedNonAccessible = false;
/* 1111 */     if ((octxt != null) && (octxt.isDelegatedRequest(mbox))) {
/* 1112 */       isDelegatedNonAccessible = !AccessManager.getInstance().canAccessAccount(octxt.getAuthenticatedUser(), conv.getAccount(), octxt.isUsingAdminPrivileges());
/*      */     }
/*      */     
/* 1115 */     if ((isDelegatedNonAccessible) || (conv.isTagged(Flag.FlagInfo.DELETED))) {
/* 1116 */       msgs = mbox.getMessagesByConversation(octxt, conv.getId(), SortBy.DATE_ASC, -1);
/*      */     }
/* 1118 */     return encodeConversationSummary(parent, ifmt, octxt, conv, msgs, msgHit, output, fields, alwaysSerialize);
/*      */   }
/*      */   
/*      */   private static Element encodeConversationSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, List<Message> msgs, Message msgHit, OutputParticipants output, int fields, boolean alwaysSerialize)
/*      */     throws ServiceException
/*      */   {
/* 1124 */     boolean addFirstHitRecips = (msgHit != null) && (output == OutputParticipants.PUT_RECIPIENTS);
/* 1125 */     boolean addAggregatedRecips = (!addFirstHitRecips) && (output == OutputParticipants.PUT_BOTH);
/* 1126 */     boolean addSenders = ((output == OutputParticipants.PUT_BOTH) || (output == OutputParticipants.PUT_SENDERS)) && (needToOutput(fields, 2048));
/*      */     
/*      */ 
/* 1129 */     Mailbox mbox = conv.getMailbox();
/*      */     
/* 1131 */     boolean noneVisible = (msgs != null) && (msgs.isEmpty());
/* 1132 */     Element c = (noneVisible) && (!alwaysSerialize) ? null : encodeConversationCommon(parent, ifmt, octxt, conv, msgs, fields);
/* 1133 */     if ((noneVisible) || (c == null)) {
/* 1134 */       return c;
/*      */     }
/* 1136 */     if (needToOutput(fields, 32)) {
/* 1137 */       c.addAttribute("d", msgHit != null ? msgHit.getDate() : conv.getDate());
/*      */     }
/* 1139 */     if (needToOutput(fields, 64)) {
/* 1140 */       c.addAttribute("su", msgHit != null ? msgHit.getSubject() : conv.getSubject(), Element.Disposition.CONTENT);
/*      */     }
/* 1142 */     if (needToOutput(fields, 5)) {
/* 1143 */       c.addAttribute("u", conv.getUnreadCount());
/*      */     }
/* 1145 */     List<Message> msgsByConv = null;
/* 1146 */     if ((fields == -4194305) && (msgHit != null))
/*      */     {
/*      */ 
/*      */ 
/*      */ 
/* 1151 */       if ((msgHit.inTrash()) || (msgHit.inSpam())) {
/* 1152 */         msgsByConv = mbox.getMessagesByConversation(octxt, conv.getId(), SortBy.DATE_DESC, 1);
/*      */       } else {
/* 1154 */         msgsByConv = mbox.getMessagesByConversation(octxt, conv.getId(), SortBy.DATE_DESC, -1, true);
/*      */       }
/* 1156 */       c.addAttribute("fr", !msgsByConv.isEmpty() ? ((Message)msgsByConv.get(0)).getFragment() : msgHit.getFragment(), Element.Disposition.CONTENT);
/*      */     }
/* 1158 */     if ((addFirstHitRecips) && (msgHit != null)) {
/* 1159 */       addEmails(c, Mime.parseAddressHeader(msgHit.getRecipients()), EmailType.TO);
/*      */     }
/* 1161 */     boolean elided = false;
/* 1162 */     if (addSenders) {
/*      */       SenderList sl;
/*      */       try { SenderList sl;
/* 1165 */         if (msgs != null) {
/* 1166 */           sl = new SenderList();
/* 1167 */           for (Message msg : msgs) {
/* 1168 */             if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 1169 */               sl.add(msg);
/*      */             }
/*      */           }
/*      */         } else {
/* 1173 */           sl = mbox.getConversationSenderList(conv.getId());
/*      */         }
/*      */       } catch (SenderList.RefreshException slre) {
/* 1176 */         ZimbraLog.soap.warn("out-of-order messages returned for conversation " + conv.getId());
/* 1177 */         return c;
/*      */       } catch (ServiceException e) {
/* 1179 */         return c;
/*      */       }
/*      */       
/* 1182 */       elided = (elided) || (sl.isElided());
/* 1183 */       for (ParsedAddress pa : sl.getLastAddresses()) {
/* 1184 */         encodeEmail(c, pa, EmailType.FROM);
/*      */       }
/*      */     }
/* 1187 */     if (addAggregatedRecips)
/*      */     {
/* 1189 */       ToRecipsList aggregatedToRecips = new ToRecipsList();
/* 1190 */       if (msgs != null) {
/* 1191 */         for (Message msg : msgs) {
/* 1192 */           if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 1193 */             aggregatedToRecips.add(msg);
/*      */           }
/*      */         }
/*      */       } else {
/* 1197 */         if (msgsByConv == null) {
/* 1198 */           msgsByConv = mbox.getMessagesByConversation(octxt, conv.getId(), SortBy.DATE_DESC, -1, true);
/*      */         }
/* 1200 */         if (msgsByConv != null) {
/* 1201 */           for (Message msg : msgsByConv) {
/* 1202 */             if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 1203 */               aggregatedToRecips.add(msg);
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/* 1208 */       elided = (elided) || (aggregatedToRecips.isElided());
/* 1209 */       for (ParsedAddress pa : aggregatedToRecips.getLastAddresses()) {
/* 1210 */         encodeEmail(c, pa, EmailType.TO);
/*      */       }
/*      */     }
/* 1213 */     if (elided) {
/* 1214 */       c.addAttribute("elided", true);
/*      */     }
/*      */     
/* 1217 */     if (needToOutput(fields, 4194304)) {
/* 1218 */       c.addAttribute("md", conv.getChangeDate() / 1000L);
/* 1219 */       c.addAttribute("ms", conv.getModifiedSequence());
/*      */     }
/*      */     
/* 1222 */     return c;
/*      */   }
/*      */   
/*      */   private static Element encodeConversationCommon(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Conversation conv, List<Message> msgs, int fields) throws ServiceException
/*      */   {
/* 1227 */     Element c = parent.addElement("c");
/* 1228 */     c.addAttribute("id", ifmt.formatItemId(conv));
/*      */     
/* 1230 */     if (needToOutput(fields, 524288)) {
/* 1231 */       encodeAllCustomMetadata(c, conv, fields);
/*      */     }
/* 1233 */     if (needToOutput(fields, 1040)) {
/* 1234 */       int count = conv.getMessageCount();int nondeleted = count;
/* 1235 */       if (msgs != null) {
/* 1236 */         count = nondeleted = msgs.size();
/* 1237 */         for (Message msg : msgs) {
/* 1238 */           if (msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 1239 */             nondeleted--;
/*      */           }
/*      */         }
/*      */       }
/* 1243 */       c.addAttribute("u", conv.getUnreadCount());
/* 1244 */       c.addAttribute("n", nondeleted);
/* 1245 */       if (count != nondeleted) {
/* 1246 */         c.addAttribute("total", count);
/*      */       }
/*      */     }
/*      */     
/* 1250 */     if (msgs == null) {
/* 1251 */       recordItemTags(c, conv, octxt, fields);
/* 1252 */     } else if (needToOutput(fields, 7)) {
/* 1253 */       int flags = 0;
/* 1254 */       Set<String> tags = Sets.newHashSet();
/* 1255 */       Set<Integer> tagIds = Sets.newTreeSet();
/* 1256 */       for (Message msg : msgs) {
/* 1257 */         if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 1258 */           flags |= msg.getFlagBitmask();
/* 1259 */           tags.addAll(Arrays.asList(msg.getTags()));
/* 1260 */           tagIds.addAll(TagUtil.getTagIds(msg));
/*      */         }
/*      */       }
/* 1263 */       if ((needToOutput(fields, 5)) && (
/* 1264 */         (fields != -4194305) || (flags != 0))) {
/* 1265 */         c.addAttribute("f", Flag.toString(flags));
/*      */       }
/*      */       
/* 1268 */       if ((needToOutput(fields, 2)) && (
/* 1269 */         (fields != -4194305) || (!tags.isEmpty()))) {
/* 1270 */         c.addAttribute("tn", TagUtil.encodeTags(tags));
/* 1271 */         if (hasFullAccess(conv.getMailbox(), octxt)) {
/* 1272 */           c.addAttribute("t", Joiner.on(',').join(tagIds));
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*      */ 
/* 1278 */     return c;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static final int MAX_INLINE_MSG_SIZE = 40000;
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeMessageAsMP(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, String part, int maxSize, boolean wantHTML, boolean neuter, Set<String> headers, boolean serializeType, boolean wantExpandGroupInfo, boolean encodeMissingBlobs)
/*      */     throws ServiceException
/*      */   {
/* 1302 */     Mailbox mbox = msg.getMailbox();
/* 1303 */     int changeId = msg.getSavedSequence();
/*      */     try
/*      */     {
/* 1306 */       return encodeMessageAsMP(parent, ifmt, octxt, msg, part, maxSize, wantHTML, neuter, headers, serializeType, wantExpandGroupInfo, false, encodeMissingBlobs);
/*      */     }
/*      */     catch (ServiceException e) {
/*      */       try {
/*      */         for (;;) {
/* 1311 */           msg = mbox.getMessageById(octxt, msg.getId());
/* 1312 */           if (msg.getSavedSequence() == changeId) {
/*      */             break;
/*      */           }
/* 1315 */           changeId = msg.getSavedSequence();
/* 1316 */           ZimbraLog.soap.info("caught message content change while serializing; will retry");
/*      */         }
/*      */       }
/*      */       catch (MailServiceException.NoSuchItemException nsie)
/*      */       {
/* 1321 */         throw nsie;
/*      */       }
/*      */       
/*      */ 
/* 1325 */       ZimbraLog.soap.warn("could not serialize full message structure in response", e); }
/* 1326 */     return encodeMessageAsMP(parent, ifmt, octxt, msg, part, maxSize, wantHTML, neuter, headers, serializeType, wantExpandGroupInfo, true);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static final String CONTENT_SERVLET_URI = "/service/content/get?id=";
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static final String PART_PARAM_STRING = "&part=";
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static Element encodeMessageAsMP(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, String part, int maxSize, boolean wantHTML, boolean neuter, Set<String> headers, boolean serializeType, boolean wantExpandGroupInfo, boolean bestEffort, boolean encodeMissingBlobs)
/*      */     throws ServiceException
/*      */   {
/* 1355 */     Element m = null;
/* 1356 */     boolean success = false;
/*      */     try {
/* 1358 */       boolean wholeMessage = (part == null) || (part.trim().isEmpty());
/* 1359 */       if (wholeMessage) {
/* 1360 */         m = encodeMessageCommon(parent, ifmt, octxt, msg, -4194305, serializeType);
/* 1361 */         m.addAttribute("id", ifmt.formatItemId(msg));
/*      */       } else {
/* 1363 */         m = parent.addElement("m");
/* 1364 */         m.addAttribute("id", ifmt.formatItemId(msg));
/* 1365 */         m.addAttribute("part", part);
/*      */       }
/*      */       
/* 1368 */       MimeMessage mm = null;
/*      */       try {
/* 1370 */         mm = msg.getMimeMessage();
/*      */       } catch (MailServiceException e) {
/* 1372 */         if ((encodeMissingBlobs) && ("mail.NO_SUCH_BLOB".equals(e.getCode()))) {
/* 1373 */           ZimbraLog.mailbox.error("Unable to get blob while encoding message", e);
/* 1374 */           encodeEmail(m, msg.getSender(), EmailType.FROM);
/* 1375 */           encodeEmail(m, msg.getSender(), EmailType.SENDER);
/* 1376 */           if (msg.getRecipients() != null) {
/* 1377 */             addEmails(m, Mime.parseAddressHeader(msg.getRecipients()), EmailType.TO);
/*      */           }
/* 1379 */           m.addAttribute("su", msg.getSubject());
/* 1380 */           Element mimePart = m.addElement("mp");
/* 1381 */           mimePart.addAttribute("part", 1L);
/* 1382 */           mimePart.addAttribute("body", true);
/* 1383 */           mimePart.addAttribute("ct", "text/plain");
/*      */           
/* 1385 */           String errMsg = L10nUtil.getMessage(L10nUtil.MsgKey.errMissingBlob, msg.getAccount().getLocale(), new Object[] { ifmt.formatItemId(msg) });
/*      */           
/* 1387 */           m.addAttribute("fr", errMsg, Element.Disposition.CONTENT);
/* 1388 */           mimePart.addAttribute("content", errMsg, Element.Disposition.CONTENT);
/* 1389 */           success = true;
/* 1390 */           Element localElement1 = m;
/*      */           
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/* 1519 */           if ((!success) && (!bestEffort) && (m != null))
/* 1520 */             m.detach(); return localElement1;
/*      */         }
/* 1392 */         throw e;
/*      */       }
/* 1394 */       if (!wholeMessage) {
/* 1395 */         MimePart mp = Mime.getMimePart(mm, part);
/* 1396 */         if (mp == null) {
/* 1397 */           throw MailServiceException.NO_SUCH_PART(part);
/*      */         }
/* 1399 */         Object content = Mime.getMessageContent(mp);
/* 1400 */         if (!(content instanceof MimeMessage)) {
/* 1401 */           throw MailServiceException.NO_SUCH_PART(part);
/*      */         }
/* 1403 */         mm = (MimeMessage)content;
/*      */       } else {
/* 1405 */         part = "";
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/* 1411 */       String fragment = msg.getFragment();
/* 1412 */       if ((fragment != null) && (!fragment.isEmpty())) {
/* 1413 */         m.addAttribute("fr", fragment, Element.Disposition.CONTENT);
/*      */       }
/*      */       
/* 1416 */       addEmails(m, Mime.parseAddressHeader(mm, "From"), EmailType.FROM);
/* 1417 */       addEmails(m, Mime.parseAddressHeader(mm, "Sender"), EmailType.SENDER);
/* 1418 */       addEmails(m, Mime.parseAddressHeader(mm, "Reply-To"), EmailType.REPLY_TO);
/* 1419 */       addEmails(m, Mime.parseAddressHeader(mm, "To"), EmailType.TO);
/* 1420 */       addEmails(m, Mime.parseAddressHeader(mm, "Cc"), EmailType.CC);
/* 1421 */       addEmails(m, Mime.parseAddressHeader(mm, "Bcc"), EmailType.BCC);
/* 1422 */       addEmails(m, Mime.parseAddressHeader(mm.getHeader("Resent-From", null), false), EmailType.RESENT_FROM);
/*      */       
/* 1424 */       if ((!octxt.isDelegatedRequest(msg.getMailbox())) || (!octxt.isOnBehalfOfRequest(msg.getMailbox()))) {
/* 1425 */         addEmails(m, Mime.parseAddressHeader(mm, "Disposition-Notification-To"), EmailType.READ_RECEIPT);
/*      */       }
/*      */       
/* 1428 */       String calIntendedFor = msg.getCalendarIntendedFor();
/* 1429 */       m.addAttribute("cif", calIntendedFor);
/*      */       
/* 1431 */       String subject = Mime.getSubject(mm);
/* 1432 */       if (subject != null) {
/* 1433 */         m.addAttribute("su", StringUtil.stripControlCharacters(subject), Element.Disposition.CONTENT);
/*      */       }
/*      */       
/*      */ 
/* 1437 */       String messageID = mm.getMessageID();
/* 1438 */       if ((messageID != null) && (!messageID.trim().isEmpty())) {
/* 1439 */         m.addAttribute("mid", StringUtil.stripControlCharacters(messageID), Element.Disposition.CONTENT);
/*      */       }
/*      */       
/*      */ 
/* 1443 */       if ((wholeMessage) && (msg.isDraft())) {
/* 1444 */         if (!msg.getDraftOrigId().isEmpty()) {
/* 1445 */           ItemId origId = new ItemId(msg.getDraftOrigId(), msg.getMailbox().getAccountId());
/* 1446 */           m.addAttribute("origid", ifmt.formatItemId(origId));
/*      */         }
/* 1448 */         if (!msg.getDraftReplyType().isEmpty()) {
/* 1449 */           m.addAttribute("rt", msg.getDraftReplyType());
/*      */         }
/* 1451 */         if (!msg.getDraftIdentityId().isEmpty()) {
/* 1452 */           m.addAttribute("idnt", msg.getDraftIdentityId());
/*      */         }
/* 1454 */         if (!msg.getDraftAccountId().isEmpty()) {
/* 1455 */           m.addAttribute("forAcct", msg.getDraftAccountId());
/*      */         }
/* 1457 */         String inReplyTo = mm.getHeader("In-Reply-To", null);
/* 1458 */         if ((inReplyTo != null) && (!inReplyTo.isEmpty())) {
/* 1459 */           m.addAttribute("irt", StringUtil.stripControlCharacters(inReplyTo), Element.Disposition.CONTENT);
/*      */         }
/*      */         
/* 1462 */         if (msg.getDraftAutoSendTime() != 0L) {
/* 1463 */           m.addAttribute("autoSendTime", msg.getDraftAutoSendTime());
/*      */         }
/*      */       }
/*      */       
/* 1467 */       if (!wholeMessage) {
/* 1468 */         m.addAttribute("s", mm.getSize());
/*      */       }
/*      */       
/* 1471 */       Date sent = mm.getSentDate();
/* 1472 */       if (sent != null) {
/* 1473 */         m.addAttribute("sd", sent.getTime());
/*      */       }
/*      */       
/* 1476 */       Calendar resent = DateUtil.parseRFC2822DateAsCalendar(mm.getHeader("Resent-Date", null));
/* 1477 */       if (resent != null) {
/* 1478 */         m.addAttribute("rd", resent.getTimeInMillis());
/*      */       }
/*      */       
/* 1481 */       if ((msg.isInvite()) && (msg.hasCalendarItemInfos())) {
/* 1482 */         encodeInvitesForMessage(m, ifmt, octxt, msg, -4194305, neuter);
/*      */       }
/*      */       
/* 1485 */       if (headers != null) {
/* 1486 */         for (String name : headers) {
/* 1487 */           String[] values = mm.getHeader(name);
/* 1488 */           if (values != null) {
/* 1489 */             for (int i = 0; i < values.length; i++) {
/* 1490 */               m.addKeyValuePair(name, values[i], "header", "n");
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/*      */       
/* 1496 */       List<MPartInfo> parts = Mime.getParts(mm, getDefaultCharset(msg));
/* 1497 */       if ((parts != null) && (!parts.isEmpty())) {
/* 1498 */         Set<MPartInfo> bodies = Mime.getBody(parts, wantHTML);
/* 1499 */         addParts(m, (MPartInfo)parts.get(0), bodies, part, maxSize, neuter, false, getDefaultCharset(msg), bestEffort);
/*      */       }
/*      */       Account authedAcct;
/* 1502 */       if (wantExpandGroupInfo) {
/* 1503 */         ZimbraLog.gal.trace("want expand group info");
/* 1504 */         authedAcct = octxt.getAuthenticatedUser();
/* 1505 */         Account requestedAcct = msg.getMailbox().getAccount();
/* 1506 */         encodeAddrsWithGroupInfo(m, requestedAcct, authedAcct);
/*      */       } else {
/* 1508 */         ZimbraLog.gal.trace("do not want expand group info");
/*      */       }
/*      */       
/* 1511 */       success = true;
/* 1512 */       return m;
/*      */     } catch (IOException ex) {
/* 1514 */       throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */     } catch (MessagingException ex) {
/* 1516 */       throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */     }
/*      */     finally {
/* 1519 */       if ((!success) && (!bestEffort) && (m != null)) {
/* 1520 */         m.detach();
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static void setCalendarItemFields(Element calItemElem, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, int fields, boolean encodeInvites, boolean includeContent, boolean neuter)
/*      */     throws ServiceException
/*      */   {
/* 1531 */     recordItemTags(calItemElem, calItem, octxt, fields);
/*      */     
/* 1533 */     calItemElem.addAttribute("uid", calItem.getUid());
/* 1534 */     calItemElem.addAttribute("id", ifmt.formatItemId(calItem));
/* 1535 */     calItemElem.addAttribute("l", ifmt.formatItemId(new ItemId(calItem.getMailbox().getAccountId(), calItem.getFolderId())));
/*      */     
/*      */ 
/* 1538 */     if ((needToOutput(fields, 65536)) && (calItem.getSavedSequence() != 0)) {
/* 1539 */       calItemElem.addAttribute("rev", calItem.getSavedSequence());
/*      */     }
/* 1541 */     if (needToOutput(fields, 16)) {
/* 1542 */       calItemElem.addAttribute("s", calItem.getSize());
/*      */     }
/* 1544 */     if (needToOutput(fields, 32)) {
/* 1545 */       calItemElem.addAttribute("d", calItem.getDate());
/*      */     }
/* 1547 */     if (needToOutput(fields, 4194304)) {
/* 1548 */       calItemElem.addAttribute("md", calItem.getChangeDate() / 1000L);
/* 1549 */       calItemElem.addAttribute("ms", calItem.getModifiedSequence());
/*      */     }
/*      */     
/* 1552 */     boolean doDetails = (needToOutput(fields, 65536)) && (encodeInvites);
/* 1553 */     boolean isPublic = true;
/* 1554 */     boolean hasSeries = false;
/* 1555 */     boolean hasExceptions = false;
/* 1556 */     Invite[] invites = calItem.getInvites();
/* 1557 */     for (Invite inv : invites) {
/* 1558 */       if (inv.isRecurrence()) {
/* 1559 */         hasSeries = true;
/* 1560 */       } else if (inv.hasRecurId()) {
/* 1561 */         hasExceptions = true;
/*      */       }
/* 1563 */       if (!inv.isPublic()) {
/* 1564 */         isPublic = false;
/*      */       }
/* 1566 */       if (doDetails) {
/* 1567 */         encodeInvite(calItemElem, ifmt, octxt, calItem, inv, includeContent, neuter);
/*      */       }
/*      */     }
/* 1570 */     if (doDetails) {
/* 1571 */       if ((isPublic) || (allowPrivateAccess(octxt, calItem))) {
/* 1572 */         encodeCalendarReplies(calItemElem, calItem);
/*      */       }
/* 1574 */       encodeAlarmTimes(calItemElem, calItem);
/*      */     }
/* 1576 */     if ((hasExceptions) && (!hasSeries)) {
/* 1577 */       calItemElem.addAttribute("orphan", true);
/*      */     }
/*      */   }
/*      */   
/*      */   public static void setCalendarItemFields(Element calItemElem, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, int fields, boolean encodeInvites, boolean neuter) throws ServiceException
/*      */   {
/* 1583 */     setCalendarItemFields(calItemElem, ifmt, octxt, calItem, fields, encodeInvites, false, neuter);
/*      */   }
/*      */   
/*      */   public static Element encodeInvite(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem cal, Invite inv, boolean neuter)
/*      */     throws ServiceException
/*      */   {
/* 1589 */     return encodeInvite(parent, ifmt, octxt, cal, inv, false, neuter);
/*      */   }
/*      */   
/*      */   public static Element encodeInvite(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem cal, Invite inv, boolean includeContent, boolean neuter)
/*      */     throws ServiceException
/*      */   {
/* 1595 */     Element ie = parent.addElement("inv");
/* 1596 */     setCalendarItemType(ie, cal.getType());
/* 1597 */     encodeTimeZoneMap(ie, cal.getTimeZoneMap());
/*      */     
/*      */ 
/*      */ 
/* 1601 */     ie.addAttribute("seq", inv.getSeqNo());
/* 1602 */     ie.addAttribute("id", inv.getMailItemId());
/* 1603 */     ie.addAttribute("compNum", inv.getComponentNum());
/* 1604 */     if (inv.hasRecurId()) {
/* 1605 */       ie.addAttribute("recurId", inv.getRecurId().toString());
/*      */     }
/* 1607 */     encodeInviteComponent(ie, ifmt, octxt, cal, (ItemId)null, inv, -4194305, neuter);
/*      */     
/* 1609 */     if ((includeContent) && ((inv.isPublic()) || (allowPrivateAccess(octxt, cal)))) {
/* 1610 */       int invId = inv.getMailItemId();
/* 1611 */       MimeMessage mm = cal.getSubpartMessage(invId);
/* 1612 */       if (mm != null) {
/*      */         List<MPartInfo> parts;
/*      */         try {
/* 1615 */           parts = Mime.getParts(mm, getDefaultCharset(cal));
/*      */         } catch (IOException ex) {
/* 1617 */           throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */         } catch (MessagingException ex) {
/* 1619 */           throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */         }
/* 1621 */         if ((parts != null) && (!parts.isEmpty())) {
/* 1622 */           addParts(ie, (MPartInfo)parts.get(0), null, "", -1, false, true, getDefaultCharset(cal), true);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/* 1627 */     return ie;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeCalendarItemSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, int fields, boolean includeInvites, boolean includeContent)
/*      */     throws ServiceException
/*      */   {
/* 1647 */     int MAX_RETRIES = LC.calendar_item_get_max_retries.intValue();
/* 1648 */     Element elem = null;
/* 1649 */     Mailbox mbox = calItem.getMailbox();
/* 1650 */     int changeId = calItem.getSavedSequence();
/* 1651 */     int numTries = 0;
/* 1652 */     while (numTries < MAX_RETRIES) {
/* 1653 */       numTries++;
/* 1654 */       if ((calItem instanceof Appointment)) {
/* 1655 */         elem = parent.addElement("appt");
/*      */       } else {
/* 1657 */         elem = parent.addElement("task");
/*      */       }
/*      */       try {
/* 1660 */         setCalendarItemFields(elem, ifmt, octxt, calItem, fields, includeInvites, includeContent, true);
/*      */         
/* 1662 */         if (needToOutput(fields, 524288)) {
/* 1663 */           encodeAllCustomMetadata(elem, calItem, fields);
/*      */         }
/* 1665 */         return elem;
/*      */       }
/*      */       catch (ServiceException e)
/*      */       {
/* 1669 */         elem.detach();
/* 1670 */         elem = null;
/*      */         try {
/* 1672 */           calItem = mbox.getCalendarItemById(octxt, calItem.getId());
/* 1673 */           if (calItem.getSavedSequence() != changeId)
/*      */           {
/* 1675 */             changeId = calItem.getSavedSequence();
/* 1676 */             ZimbraLog.soap.info("caught calendar item content change while serializing; will retry");
/* 1677 */             continue;
/*      */           }
/*      */         }
/*      */         catch (MailServiceException.NoSuchItemException nsie) {
/* 1681 */           throw nsie;
/*      */         }
/*      */         
/*      */ 
/* 1685 */         ZimbraLog.soap.warn("Could not serialize full calendar item structure in response", e);
/*      */       }
/*      */     }
/*      */     
/* 1689 */     throw MailServiceException.NoSuchItemException.NO_SUCH_CALITEM("Problem encoding calendar item.  Maybe corrupt");
/*      */   }
/*      */   
/*      */ 
/*      */   public static Element encodeCalendarItemSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, int fields, boolean includeInvites)
/*      */     throws ServiceException
/*      */   {
/* 1696 */     return encodeCalendarItemSummary(parent, ifmt, octxt, calItem, fields, includeInvites, false);
/*      */   }
/*      */   
/*      */   public static void encodeCalendarReplies(Element parent, CalendarItem calItem, Invite inv, String recurIdZ) {
/* 1700 */     List<CalendarItem.ReplyInfo> replies = calItem.getReplyInfo(inv, recurIdZ);
/* 1701 */     encodeCalendarReplies(parent, replies);
/*      */   }
/*      */   
/*      */   public static void encodeCalendarReplies(Element parent, CalendarItem calItem) {
/* 1705 */     List<CalendarItem.ReplyInfo> replies = calItem.getAllReplies();
/* 1706 */     encodeCalendarReplies(parent, replies);
/*      */   }
/*      */   
/*      */   private static void encodeCalendarReplies(Element parent, List<CalendarItem.ReplyInfo> replies) {
/* 1710 */     if (replies.isEmpty()) {
/* 1711 */       return;
/*      */     }
/* 1713 */     List<CalendarReply> jaxbReplies = Lists.newArrayList();
/* 1714 */     for (CalendarItem.ReplyInfo repInfo : replies) {
/* 1715 */       jaxbReplies.add(repInfo.toJAXB());
/*      */     }
/* 1717 */     CalendarReply.encodeCalendarReplyList(parent, jaxbReplies);
/*      */   }
/*      */   
/*      */   private static String getDefaultCharset(MailItem item) throws ServiceException {
/* 1721 */     Account acct = item == null ? null : item.getAccount();
/* 1722 */     return acct == null ? null : acct.getAttr("zimbraPrefMailDefaultCharset", null);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeInviteAsMP(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, String recurIdZ, ItemId iid, String part, int maxSize, boolean wantHTML, boolean neuter, Set<String> headers, boolean serializeType, boolean wantExpandGroupInfo)
/*      */     throws ServiceException
/*      */   {
/* 1748 */     int invId = iid.getSubpartId();
/* 1749 */     Invite[] invites = calItem.getInvites(invId);
/* 1750 */     boolean isPublic = calItem.isPublic();
/* 1751 */     boolean showAll = (isPublic) || (allowPrivateAccess(octxt, calItem));
/*      */     
/* 1753 */     boolean wholeMessage = (part == null) || (part.trim().isEmpty());
/*      */     
/*      */     Element m;
/* 1756 */     if (wholeMessage)
/*      */     {
/* 1758 */       int fields = -1;
/* 1759 */       Element m = encodeMessageCommon(parent, ifmt, octxt, calItem, fields, serializeType);
/* 1760 */       m.addAttribute("id", ifmt.formatItemId(calItem, invId));
/*      */     } else {
/* 1762 */       m = parent.addElement("m");
/* 1763 */       m.addAttribute("id", ifmt.formatItemId(calItem, invId));
/* 1764 */       m.addAttribute("part", part);
/*      */     }
/*      */     try
/*      */     {
/* 1768 */       MimeMessage mm = calItem.getSubpartMessage(invId);
/* 1769 */       if (mm != null) {
/* 1770 */         if (!wholeMessage) {
/* 1771 */           MimePart mp = Mime.getMimePart(mm, part);
/* 1772 */           if (mp == null) {
/* 1773 */             throw MailServiceException.NO_SUCH_PART(part);
/*      */           }
/* 1775 */           Object content = Mime.getMessageContent(mp);
/* 1776 */           if (!(content instanceof MimeMessage)) {
/* 1777 */             throw MailServiceException.NO_SUCH_PART(part);
/*      */           }
/* 1779 */           mm = (MimeMessage)content;
/*      */         } else {
/* 1781 */           part = "";
/*      */         }
/* 1783 */         if (showAll) {
/* 1784 */           addEmails(m, Mime.parseAddressHeader(mm, "From"), EmailType.FROM);
/* 1785 */           addEmails(m, Mime.parseAddressHeader(mm, "Sender"), EmailType.SENDER);
/* 1786 */           addEmails(m, Mime.parseAddressHeader(mm, "Reply-To"), EmailType.REPLY_TO);
/* 1787 */           addEmails(m, Mime.parseAddressHeader(mm, "To"), EmailType.TO);
/* 1788 */           addEmails(m, Mime.parseAddressHeader(mm, "Cc"), EmailType.CC);
/* 1789 */           addEmails(m, Mime.parseAddressHeader(mm, "Bcc"), EmailType.BCC);
/*      */           
/* 1791 */           String subject = Mime.getSubject(mm);
/* 1792 */           if (subject != null) {
/* 1793 */             m.addAttribute("su", StringUtil.stripControlCharacters(subject), Element.Disposition.CONTENT);
/*      */           }
/*      */           
/* 1796 */           String messageID = mm.getMessageID();
/* 1797 */           if ((messageID != null) && (!messageID.trim().isEmpty())) {
/* 1798 */             m.addAttribute("mid", StringUtil.stripControlCharacters(messageID), Element.Disposition.CONTENT);
/*      */           }
/*      */           
/* 1801 */           if (!wholeMessage) {
/* 1802 */             m.addAttribute("s", mm.getSize());
/*      */           }
/* 1804 */           Date sent = mm.getSentDate();
/* 1805 */           if (sent != null) {
/* 1806 */             m.addAttribute("sd", sent.getTime());
/*      */           }
/*      */         }
/*      */       }
/*      */       
/* 1811 */       Element invElt = m.addElement("inv");
/* 1812 */       setCalendarItemType(invElt, calItem.getType());
/* 1813 */       encodeTimeZoneMap(invElt, calItem.getTimeZoneMap());
/* 1814 */       if (invites.length > 0) {
/* 1815 */         if (showAll) {
/* 1816 */           encodeCalendarReplies(invElt, calItem, invites[0], recurIdZ);
/*      */         }
/* 1818 */         for (Invite inv : invites) {
/* 1819 */           encodeInviteComponent(invElt, ifmt, octxt, calItem, (ItemId)null, inv, -4194305, neuter);
/*      */         }
/*      */       }
/*      */       
/*      */ 
/*      */ 
/* 1825 */       if ((mm != null) && (showAll)) {
/* 1826 */         if (headers != null) {
/* 1827 */           for (String name : headers) {
/* 1828 */             String[] values = mm.getHeader(name);
/* 1829 */             if (values != null)
/*      */             {
/*      */ 
/* 1832 */               for (int i = 0; i < values.length; i++) {
/* 1833 */                 m.addKeyValuePair(name, values[i], "header", "n");
/*      */               }
/*      */             }
/*      */           }
/*      */         }
/* 1838 */         List<MPartInfo> parts = Mime.getParts(mm, getDefaultCharset(calItem));
/* 1839 */         if ((parts != null) && (!parts.isEmpty())) {
/* 1840 */           Set<MPartInfo> bodies = Mime.getBody(parts, wantHTML);
/* 1841 */           addParts(m, (MPartInfo)parts.get(0), bodies, part, maxSize, neuter, true, getDefaultCharset(calItem), true);
/*      */         }
/*      */       }
/*      */       
/* 1845 */       if (wantExpandGroupInfo) {
/* 1846 */         Account authedAcct = octxt.getAuthenticatedUser();
/* 1847 */         Account requestedAcct = calItem.getMailbox().getAccount();
/* 1848 */         encodeAddrsWithGroupInfo(m, requestedAcct, authedAcct);
/*      */       }
/*      */     } catch (IOException ex) {
/* 1851 */       throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */     } catch (MessagingException ex) {
/* 1853 */       throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */     }
/* 1855 */     return m;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Element encodeMessageAsMIME(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, String part, boolean serializeType)
/*      */     throws ServiceException
/*      */   {
/* 1868 */     return encodeMessageAsMIME(parent, ifmt, octxt, msg, part, false, serializeType);
/*      */   }
/*      */   
/*      */   public static Element encodeMessageAsMIME(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, String part, boolean mustInline, boolean serializeType) throws ServiceException
/*      */   {
/* 1873 */     boolean wholeMessage = (part == null) || (part.trim().isEmpty());
/*      */     
/*      */     Element m;
/* 1876 */     if (wholeMessage) {
/* 1877 */       Element m = encodeMessageCommon(parent, ifmt, octxt, msg, -4194305, serializeType);
/* 1878 */       m.addAttribute("id", ifmt.formatItemId(msg));
/*      */     } else {
/* 1880 */       m = parent.addElement("m");
/* 1881 */       m.addAttribute("id", ifmt.formatItemId(msg));
/* 1882 */       m.addAttribute("part", part);
/*      */     }
/*      */     
/* 1885 */     Element content = m.addUniqueElement("content");
/* 1886 */     long size = msg.getSize() + 2048L;
/* 1887 */     if (!wholeMessage) {
/* 1888 */       content.addAttribute("url", "/service/content/get?id=" + ifmt.formatItemId(msg) + "&part=" + part);
/*      */     }
/* 1890 */     else if ((!mustInline) && (size > 40000L)) {
/* 1891 */       content.addAttribute("url", "/service/content/get?id=" + ifmt.formatItemId(msg));
/*      */     } else {
/*      */       try {
/* 1894 */         byte[] raw = msg.getContent();
/* 1895 */         if (!ByteUtil.isASCII(raw)) {
/* 1896 */           if (!mustInline) {
/* 1897 */             content.addAttribute("url", "/service/content/get?id=" + ifmt.formatItemId(msg));
/*      */           }
/*      */           else {
/* 1900 */             content.setText(new String(raw, "utf-8"));
/*      */           }
/*      */         } else {
/* 1903 */           content.setText(new String(raw, "US-ASCII"));
/*      */         }
/*      */       } catch (IOException ex) {
/* 1906 */         throw ServiceException.FAILURE(ex.getMessage(), ex);
/*      */       }
/*      */     }
/*      */     
/* 1910 */     return m;
/*      */   }
/*      */   
/*      */   public static Element encodeMessageSummary(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, OutputParticipants output, int fields) throws ServiceException
/*      */   {
/* 1915 */     Element el = encodeMessageCommon(parent, ifmt, octxt, msg, fields, true);
/* 1916 */     el.addAttribute("id", ifmt.formatItemId(msg));
/* 1917 */     if (!needToOutput(fields, 65536)) {
/* 1918 */       return el;
/*      */     }
/* 1920 */     boolean addRecips = (output == OutputParticipants.PUT_RECIPIENTS) || (output == OutputParticipants.PUT_BOTH);
/* 1921 */     boolean addSenders = (output == OutputParticipants.PUT_BOTH) || (output == OutputParticipants.PUT_SENDERS);
/* 1922 */     if (addRecips) {
/* 1923 */       addEmails(el, Mime.parseAddressHeader(msg.getRecipients()), EmailType.TO);
/*      */     }
/* 1925 */     if (addSenders) {
/* 1926 */       encodeEmail(el, msg.getSender(), EmailType.FROM);
/*      */     }
/* 1928 */     el.addAttribute("su", StringUtil.stripControlCharacters(msg.getSubject()), Element.Disposition.CONTENT);
/*      */     
/*      */ 
/*      */ 
/* 1932 */     String fragment = msg.getFragment();
/* 1933 */     if (!fragment.isEmpty()) {
/* 1934 */       el.addAttribute("fr", fragment, Element.Disposition.CONTENT);
/*      */     }
/* 1936 */     if ((msg.isInvite()) && (msg.hasCalendarItemInfos())) {
/*      */       try {
/* 1938 */         encodeInvitesForMessage(el, ifmt, octxt, msg, fields, true);
/*      */       } catch (ServiceException ex) {
/* 1940 */         LOG.debug("Caught exception while encoding Invites for msg " + msg.getId(), ex);
/*      */       }
/*      */     }
/*      */     
/* 1944 */     if ((msg.isDraft()) && (msg.getDraftAutoSendTime() != 0L)) {
/* 1945 */       el.addAttribute("autoSendTime", msg.getDraftAutoSendTime());
/*      */     }
/* 1947 */     return el;
/*      */   }
/*      */   
/*      */   private static Element encodeMessageCommon(Element parent, ItemIdFormatter ifmt, OperationContext octxt, MailItem item, int fields, boolean serializeType) throws ServiceException
/*      */   {
/* 1952 */     String name = (serializeType) && ((item instanceof Chat)) ? "chat" : "m";
/* 1953 */     Element elem = parent.addElement(name);
/*      */     
/* 1955 */     if (needToOutput(fields, 16)) {
/* 1956 */       elem.addAttribute("s", item.getSize());
/*      */     }
/* 1958 */     if (needToOutput(fields, 32)) {
/* 1959 */       elem.addAttribute("d", item.getDate());
/*      */     }
/* 1961 */     if (needToOutput(fields, 256)) {
/* 1962 */       elem.addAttribute("l", ifmt.formatItemId(new ItemId(item.getMailbox().getAccountId(), item.getFolderId())));
/*      */     }
/*      */     
/* 1965 */     if ((item instanceof Message)) {
/* 1966 */       Message msg = (Message)item;
/* 1967 */       if ((needToOutput(fields, 512)) && ((fields != -4194305) || (msg.getConversationId() != -1)))
/*      */       {
/* 1969 */         elem.addAttribute("cid", ifmt.formatItemId(msg.getConversationId()));
/*      */       }
/*      */     }
/* 1972 */     recordItemTags(elem, item, octxt, fields);
/* 1973 */     if (needToOutput(fields, 524288)) {
/* 1974 */       encodeAllCustomMetadata(elem, item, fields);
/*      */     }
/* 1976 */     if (needToOutput(fields, 4194304)) {
/* 1977 */       elem.addAttribute("rev", item.getSavedSequence());
/* 1978 */       elem.addAttribute("md", item.getChangeDate() / 1000L);
/* 1979 */       elem.addAttribute("ms", item.getModifiedSequence());
/* 1980 */     } else if ((needToOutput(fields, 65536)) && (item.getSavedSequence() != 0)) {
/* 1981 */       elem.addAttribute("rev", item.getSavedSequence());
/*      */     }
/*      */     
/* 1984 */     return elem;
/*      */   }
/*      */   
/*      */   private static void encodeTimeZoneMap(Element parent, TimeZoneMap tzmap) {
/* 1988 */     assert (tzmap != null);
/* 1989 */     for (Iterator<ICalTimeZone> iter = tzmap.tzIterator(); iter.hasNext();) {
/* 1990 */       ICalTimeZone tz = (ICalTimeZone)iter.next();
/* 1991 */       Element e = parent.addElement("tz");
/* 1992 */       e.addAttribute("id", tz.getID());
/* 1993 */       e.addAttribute("stdoff", tz.getStandardOffset() / 60 / 1000);
/* 1994 */       e.addAttribute("stdname", tz.getStandardTzname());
/*      */       
/* 1996 */       if (tz.useDaylightTime()) {
/* 1997 */         ICalTimeZone.SimpleOnset standard = tz.getStandardOnset();
/* 1998 */         ICalTimeZone.SimpleOnset daylight = tz.getDaylightOnset();
/* 1999 */         if ((standard != null) && (daylight != null)) {
/* 2000 */           e.addAttribute("dayoff", tz.getDaylightOffset() / 60 / 1000);
/* 2001 */           e.addAttribute("dayname", tz.getDaylightTzname());
/*      */           
/* 2003 */           Element std = e.addElement("standard");
/* 2004 */           int standardWeek = standard.getWeek();
/* 2005 */           if (standardWeek != 0) {
/* 2006 */             std.addAttribute("week", standardWeek);
/* 2007 */             std.addAttribute("wkday", standard.getDayOfWeek());
/*      */           } else {
/* 2009 */             std.addAttribute("mday", standard.getDayOfMonth());
/*      */           }
/* 2011 */           std.addAttribute("mon", standard.getMonth());
/* 2012 */           std.addAttribute("hour", standard.getHour());
/* 2013 */           std.addAttribute("min", standard.getMinute());
/* 2014 */           std.addAttribute("sec", standard.getSecond());
/*      */           
/* 2016 */           Element day = e.addElement("daylight");
/* 2017 */           int daylightWeek = daylight.getWeek();
/* 2018 */           if (daylightWeek != 0) {
/* 2019 */             day.addAttribute("week", daylightWeek);
/* 2020 */             day.addAttribute("wkday", daylight.getDayOfWeek());
/*      */           } else {
/* 2022 */             day.addAttribute("mday", daylight.getDayOfMonth());
/*      */           }
/* 2024 */           day.addAttribute("mon", daylight.getMonth());
/* 2025 */           day.addAttribute("hour", daylight.getHour());
/* 2026 */           day.addAttribute("min", daylight.getMinute());
/* 2027 */           day.addAttribute("sec", daylight.getSecond());
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static boolean allowPrivateAccess(OperationContext octxt, CalendarItem calItem) throws ServiceException {
/* 2034 */     Account authAccount = octxt != null ? octxt.getAuthenticatedUser() : null;
/* 2035 */     boolean asAdmin = octxt != null ? octxt.isUsingAdminPrivileges() : false;
/* 2036 */     return calItem.allowPrivateAccess(authAccount, asAdmin);
/*      */   }
/*      */   
/*      */ 
/*      */   public static Element encodeInviteComponent(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, ItemId calId, Invite invite, int fields, boolean neuter)
/*      */     throws ServiceException
/*      */   {
/* 2043 */     boolean allFields = true;
/*      */     
/* 2045 */     if (fields != -4194305) {
/* 2046 */       allFields = false;
/* 2047 */       if (!needToOutput(fields, 131072)) {
/* 2048 */         return parent;
/*      */       }
/*      */     }
/*      */     
/* 2052 */     Element e = parent.addElement("comp");
/* 2053 */     e.addAttribute("method", invite.getMethod());
/* 2054 */     e.addAttribute("compNum", invite.getComponentNum());
/* 2055 */     e.addAttribute("rsvp", invite.getRsvp());
/*      */     
/* 2057 */     boolean allowPrivateAccess = calItem != null ? allowPrivateAccess(octxt, calItem) : true;
/* 2058 */     if (allFields) {
/* 2059 */       if ((invite.isPublic()) || (allowPrivateAccess)) {
/* 2060 */         String priority = invite.getPriority();
/* 2061 */         if (priority != null) {
/* 2062 */           e.addAttribute("priority", priority);
/*      */         }
/* 2064 */         e.addAttribute("name", invite.getName());
/* 2065 */         e.addAttribute("loc", invite.getLocation());
/*      */         
/* 2067 */         List<String> categories = invite.getCategories();
/* 2068 */         if (categories != null) {
/* 2069 */           for (String cat : categories) {
/* 2070 */             e.addElement("category").setText(cat);
/*      */           }
/*      */         }
/* 2073 */         List<String> comments = invite.getComments();
/* 2074 */         if (comments != null) {
/* 2075 */           for (String cmt : comments) {
/* 2076 */             e.addElement("comment").setText(cmt);
/*      */           }
/*      */         }
/* 2079 */         List<String> contacts = invite.getContacts();
/* 2080 */         if (contacts != null) {
/* 2081 */           for (String contact : contacts) {
/* 2082 */             e.addElement("contact").setText(contact);
/*      */           }
/*      */         }
/* 2085 */         Geo geo = invite.getGeo();
/* 2086 */         if (geo != null) {
/* 2087 */           geo.toXml(e);
/*      */         }
/*      */         
/* 2090 */         if (invite.isTodo()) {
/* 2091 */           String pct = invite.getPercentComplete();
/* 2092 */           if (pct != null)
/* 2093 */             e.addAttribute("percentComplete", pct);
/* 2094 */           long completed = invite.getCompleted();
/* 2095 */           if (completed != 0L) {
/* 2096 */             ParsedDateTime c = ParsedDateTime.fromUTCTime(completed);
/* 2097 */             e.addAttribute("completed", c.getDateTimePartString());
/*      */           }
/*      */         }
/*      */         
/*      */ 
/* 2102 */         List<ZAttendee> attendees = invite.getAttendees();
/* 2103 */         for (ZAttendee at : attendees) {
/* 2104 */           at.toXml(e);
/*      */         }
/*      */         
/*      */ 
/* 2108 */         Iterator<Alarm> alarmsIter = invite.alarmsIterator();
/* 2109 */         while (alarmsIter.hasNext()) {
/* 2110 */           Alarm alarm = (Alarm)alarmsIter.next();
/* 2111 */           alarm.toXml(e);
/*      */         }
/*      */         
/*      */ 
/* 2115 */         encodeXProps(e, invite.xpropsIterator());
/*      */         
/*      */ 
/* 2118 */         String fragment = invite.getFragment();
/* 2119 */         if (!Strings.isNullOrEmpty(fragment)) {
/* 2120 */           e.addAttribute("fr", fragment, Element.Disposition.CONTENT);
/*      */         }
/*      */         
/* 2123 */         if (!invite.hasBlobPart()) {
/* 2124 */           e.addAttribute("noBlob", true);
/*      */         }
/*      */         
/* 2127 */         String desc = invite.getDescription();
/* 2128 */         if (desc != null) {
/* 2129 */           Element descElem = e.addElement("desc");
/* 2130 */           descElem.setText(desc);
/*      */         }
/* 2132 */         String descHtml = invite.getDescriptionHtml();
/* 2133 */         BrowserDefang defanger = DefangFactory.getDefanger("text/html");
/* 2134 */         if (descHtml != null) {
/*      */           try {
/* 2136 */             descHtml = StringUtil.stripControlCharacters(descHtml);
/* 2137 */             descHtml = defanger.defang(descHtml, neuter);
/* 2138 */             Element descHtmlElem = e.addElement("descHtml");
/* 2139 */             descHtmlElem.setText(descHtml);
/*      */           } catch (IOException ex) {
/* 2141 */             ZimbraLog.calendar.warn("Unable to defang HTML for SetAppointmentRequest", ex);
/*      */           }
/*      */         }
/*      */         
/* 2145 */         if (invite.isEvent()) {
/* 2146 */           if ((calItem != null) && ((calItem instanceof Appointment))) {
/* 2147 */             CalendarItem.Instance inst = CalendarItem.Instance.fromInvite(calItem.getId(), invite);
/* 2148 */             Appointment appt = (Appointment)calItem;
/* 2149 */             e.addAttribute("fba", appt.getEffectiveFreeBusyActual(invite, inst));
/*      */           }
/*      */           
/* 2152 */           e.addAttribute("fb", invite.getFreeBusy());
/* 2153 */           e.addAttribute("transp", invite.getTransparency());
/*      */         }
/*      */         
/*      */ 
/* 2157 */         if (invite.hasOrganizer()) {
/* 2158 */           ZOrganizer org = invite.getOrganizer();
/* 2159 */           org.toXml(e);
/*      */         }
/* 2161 */         e.addAttribute("url", invite.getUrl());
/*      */       }
/*      */       
/* 2164 */       if (invite.isOrganizer()) {
/* 2165 */         e.addAttribute("isOrg", true);
/*      */       }
/*      */       
/* 2168 */       boolean isRecurring = false;
/* 2169 */       e.addAttribute("x_uid", invite.getUid());
/* 2170 */       e.addAttribute("uid", invite.getUid());
/* 2171 */       e.addAttribute("seq", invite.getSeqNo());
/* 2172 */       e.addAttribute("d", invite.getDTStamp());
/*      */       
/* 2174 */       String itemId = null;
/* 2175 */       if (calId != null) {
/* 2176 */         itemId = calId.toString(ifmt);
/* 2177 */       } else if (calItem != null) {
/* 2178 */         itemId = ifmt.formatItemId(calItem);
/*      */       }
/* 2180 */       if ((itemId != null) && (!"0".equals(itemId))) {
/* 2181 */         e.addAttribute("calItemId", itemId);
/* 2182 */         if (invite.isEvent()) {
/* 2183 */           e.addAttribute("apptId", itemId);
/*      */         }
/* 2185 */         if (calItem != null) {
/* 2186 */           ItemId ciFolderId = new ItemId(calItem.getMailbox(), calItem.getFolderId());
/* 2187 */           e.addAttribute("ciFolder", ifmt.formatItemId(ciFolderId));
/*      */         }
/*      */       }
/*      */       
/* 2191 */       Recurrence.IRecurrence recur = invite.getRecurrence();
/* 2192 */       if (recur != null) {
/* 2193 */         isRecurring = true;
/* 2194 */         Element recurElt = e.addElement("recur");
/* 2195 */         recur.toXml(recurElt);
/*      */       }
/*      */       
/* 2198 */       e.addAttribute("status", invite.getStatus());
/* 2199 */       e.addAttribute("class", invite.getClassProp());
/*      */       
/* 2201 */       boolean allDay = invite.isAllDayEvent();
/* 2202 */       boolean isException = invite.hasRecurId();
/* 2203 */       if (isException) {
/* 2204 */         e.addAttribute("ex", true);
/* 2205 */         RecurId rid = invite.getRecurId();
/* 2206 */         e.addAttribute("ridZ", rid.getDtZ());
/* 2207 */         encodeRecurId(e, rid, allDay);
/*      */       }
/*      */       
/* 2210 */       boolean forceUTC = (DebugConfig.calendarForceUTC) && (!isRecurring) && (!isException) && (!allDay);
/* 2211 */       ParsedDateTime dtStart = invite.getStartTime();
/* 2212 */       if (dtStart != null) {
/* 2213 */         encodeDtStart(e, dtStart, allDay, forceUTC);
/*      */       }
/* 2215 */       ParsedDateTime dtEnd = invite.getEndTime();
/* 2216 */       if (dtEnd != null) {
/* 2217 */         encodeDtEnd(e, dtEnd, allDay, invite.isTodo(), forceUTC);
/*      */       }
/* 2219 */       ParsedDuration dur = invite.getDuration();
/* 2220 */       if (dur != null) {
/* 2221 */         dur.toXml(e);
/*      */       }
/* 2223 */       if (allDay) {
/* 2224 */         e.addAttribute("allDay", true);
/*      */       }
/* 2226 */       if (invite.isDraft()) {
/* 2227 */         e.addAttribute("draft", true);
/*      */       }
/* 2229 */       if (invite.isNeverSent()) {
/* 2230 */         e.addAttribute("neverSent", true);
/*      */       }
/*      */     }
/*      */     
/* 2234 */     return e;
/*      */   }
/*      */   
/*      */   public static List<XParam> jaxbXParams(Iterator<ZCalendar.ZParameter> xparamsIterator) {
/* 2238 */     List<XParam> xparams = Lists.newArrayList();
/* 2239 */     while (xparamsIterator.hasNext()) {
/* 2240 */       ZCalendar.ZParameter xparam = (ZCalendar.ZParameter)xparamsIterator.next();
/* 2241 */       String paramName = xparam.getName();
/* 2242 */       if (paramName != null)
/*      */       {
/*      */ 
/* 2245 */         xparams.add(new XParam(paramName, xparam.getValue())); }
/*      */     }
/* 2247 */     return Collections.unmodifiableList(xparams);
/*      */   }
/*      */   
/*      */   public static List<XProp> jaxbXProps(Iterator<ZCalendar.ZProperty> xpropsIterator) {
/* 2251 */     List<XProp> xprops = Lists.newArrayList();
/* 2252 */     while (xpropsIterator.hasNext()) {
/* 2253 */       ZCalendar.ZProperty xprop = (ZCalendar.ZProperty)xpropsIterator.next();
/* 2254 */       String paramName = xprop.getName();
/* 2255 */       if (paramName != null)
/*      */       {
/*      */ 
/* 2258 */         XProp xp = new XProp(paramName, xprop.getValue());
/* 2259 */         xp.setXParams(jaxbXParams(xprop.parameterIterator()));
/* 2260 */         xprops.add(xp);
/*      */       } }
/* 2262 */     return Collections.unmodifiableList(xprops);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static void encodeXProps(Element parent, Iterator<ZCalendar.ZProperty> xpropsIterator)
/*      */   {
/* 2269 */     while (xpropsIterator.hasNext()) {
/* 2270 */       ZCalendar.ZProperty xprop = (ZCalendar.ZProperty)xpropsIterator.next();
/* 2271 */       String propName = xprop.getName();
/* 2272 */       if (propName != null)
/*      */       {
/*      */ 
/* 2275 */         String propValue = xprop.getValue();
/* 2276 */         Element propElem = parent.addElement("xprop");
/* 2277 */         propElem.addAttribute("name", propName);
/* 2278 */         if (propValue != null) {
/* 2279 */           propElem.addAttribute("value", propValue);
/*      */         }
/* 2281 */         CalendarUtil.encodeXParams(propElem, xprop.parameterIterator());
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static Element encodeInvitesForMessage(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Message msg, int fields, boolean neuter) throws ServiceException
/*      */   {
/* 2288 */     if ((fields != -4194305) && (!needToOutput(fields, 131072))) {
/* 2289 */       return parent;
/*      */     }
/*      */     
/* 2292 */     Element ie = parent.addNonUniqueElement("inv");
/*      */     
/* 2294 */     Mailbox mbox = msg.getMailbox();
/*      */     
/* 2296 */     for (Iterator<Message.CalendarItemInfo> iter = msg.getCalendarItemInfoIterator(); iter.hasNext();) {
/* 2297 */       Message.CalendarItemInfo info = (Message.CalendarItemInfo)iter.next();
/* 2298 */       CalendarItem calItem = null;
/* 2299 */       ZCalendar.ICalTok method = ZCalendar.ICalTok.REQUEST;
/* 2300 */       Invite invCi = info.getInvite();
/* 2301 */       if (invCi != null) {
/* 2302 */         method = Invite.lookupMethod(invCi.getMethod());
/*      */       }
/* 2304 */       Invite invite = invCi;
/* 2305 */       ItemId calendarItemId = info.getCalendarItemId();
/* 2306 */       if (info.calItemCreated()) {
/*      */         try {
/* 2308 */           calItem = mbox.getCalendarItemById(octxt, calendarItemId);
/*      */         }
/*      */         catch (MailServiceException.NoSuchItemException e) {
/* 2311 */           calendarItemId = null;
/*      */         }
/*      */         catch (ServiceException e) {
/* 2314 */           if (e.getCode() != "service.PERM_DENIED") {
/* 2315 */             throw e;
/*      */           }
/* 2317 */           calendarItemId = null;
/*      */         }
/*      */         
/* 2320 */         if (((ZCalendar.ICalTok.REQUEST.equals(method)) || (ZCalendar.ICalTok.PUBLISH.equals(method))) && 
/* 2321 */           (calItem != null) && (calItem.getFolderId() != 3)) {
/* 2322 */           if (invCi != null)
/*      */           {
/* 2324 */             Invite invCurr = calItem.getInvite(invCi.getRecurId());
/* 2325 */             if (invCurr != null) {
/* 2326 */               if (invCi.getSeqNo() >= invCurr.getSeqNo())
/*      */               {
/* 2328 */                 invite = invCi;
/*      */               }
/*      */               else {
/* 2331 */                 invite = null;
/*      */               }
/*      */             }
/*      */             else {
/* 2335 */               invite = invCi;
/*      */             }
/*      */           }
/*      */           else {
/* 2339 */             invite = calItem.getInvite(msg.getId(), info.getComponentNo());
/*      */           }
/*      */           
/*      */         }
/*      */         
/*      */ 
/*      */       }
/* 2346 */       else if (invCi != null) {
/* 2347 */         if ((!Invite.isOrganizerMethod(invCi.getMethod())) || (ZCalendar.ICalTok.DECLINECOUNTER.equals(method))) {
/* 2348 */           invite = invCi;
/*      */         } else {
/*      */           try {
/* 2351 */             calItem = mbox.getCalendarItemByUid(octxt, invCi.getUid());
/*      */ 
/*      */           }
/*      */           catch (MailServiceException.NoSuchItemException e) {}catch (ServiceException e)
/*      */           {
/* 2356 */             if (e.getCode() != "service.PERM_DENIED") {
/* 2357 */               throw e;
/*      */             }
/*      */           }
/* 2360 */           if (calItem != null)
/*      */           {
/* 2362 */             Invite invCurr = calItem.getInvite(invCi.getRecurId());
/* 2363 */             if (invCurr != null) {
/* 2364 */               if (invCi.getSeqNo() >= invCurr.getSeqNo())
/*      */               {
/* 2366 */                 invite = invCi;
/*      */               }
/*      */               else {
/* 2369 */                 invite = null;
/*      */               }
/*      */             }
/*      */             else {
/* 2373 */               invite = invCi;
/*      */             }
/*      */           }
/*      */           else
/*      */           {
/* 2378 */             invite = invCi;
/*      */           }
/*      */         }
/*      */       }
/*      */       
/*      */ 
/* 2384 */       if (invite != null) {
/* 2385 */         setCalendarItemType(ie, invite.getItemType());
/* 2386 */         encodeTimeZoneMap(ie, invite.getTimeZoneMap());
/* 2387 */         CalendarItemInfo remoteCalendarItem = null;
/* 2388 */         if (calItem == null) {
/* 2389 */           remoteCalendarItem = msg.getRemoteCalendarItem(invite);
/* 2390 */           if (remoteCalendarItem != null) {
/* 2391 */             calendarItemId = new ItemId(remoteCalendarItem.getId(), (String)null);
/*      */           }
/*      */         }
/* 2394 */         encodeInviteComponent(ie, ifmt, octxt, calItem, calendarItemId, invite, fields, neuter);
/* 2395 */         ZCalendar.ICalTok invMethod = Invite.lookupMethod(invite.getMethod());
/* 2396 */         if ((ZCalendar.ICalTok.REQUEST.equals(invMethod)) || (ZCalendar.ICalTok.PUBLISH.equals(invMethod))) {
/* 2397 */           InviteChanges invChanges = info.getInviteChanges();
/* 2398 */           if ((invChanges != null) && (!invChanges.noChange())) {
/* 2399 */             Element comp = ie.getOptionalElement("comp");
/* 2400 */             if (comp != null) {
/* 2401 */               comp.addAttribute("changes", invChanges.toString());
/*      */             }
/*      */           }
/* 2404 */           if (calItem != null) {
/* 2405 */             boolean showAll = (invite.isPublic()) || (allowPrivateAccess(octxt, calItem));
/* 2406 */             if (showAll) {
/* 2407 */               RecurId rid = invite.getRecurId();
/* 2408 */               encodeCalendarReplies(ie, calItem, invite, rid != null ? rid.getDtZ() : null);
/*      */             }
/* 2410 */           } else if (null != remoteCalendarItem) {
/* 2411 */             CalendarReply.encodeCalendarReplyList(ie, remoteCalendarItem.getCalendarReplies());
/*      */           }
/*      */         }
/*      */       }
/*      */     }
/*      */     
/* 2417 */     return ie;
/*      */   }
/*      */   
/* 2420 */   private static enum VisitPhase { PREVISIT,  POSTVISIT;
/*      */     
/*      */     private VisitPhase() {}
/*      */   }
/*      */   
/* 2425 */   private static void addParts(Element root, MPartInfo mpiRoot, Set<MPartInfo> bodies, String prefix, int maxSize, boolean neuter, boolean excludeCalendarParts, String defaultCharset, boolean swallowContentExceptions) throws ServiceException { MPartInfo mpi = mpiRoot;
/* 2426 */     LinkedList<Pair<Element, LinkedList<MPartInfo>>> queue = new LinkedList();
/* 2427 */     Pair<Element, LinkedList<MPartInfo>> level = new Pair(root, new LinkedList());
/* 2428 */     ((LinkedList)level.getSecond()).add(mpi);
/* 2429 */     queue.add(level);
/*      */     
/* 2431 */     VisitPhase phase = VisitPhase.PREVISIT;
/* 2432 */     while (!queue.isEmpty()) {
/* 2433 */       level = (Pair)queue.getLast();
/* 2434 */       LinkedList<MPartInfo> parts = (LinkedList)level.getSecond();
/* 2435 */       if (parts.isEmpty()) {
/* 2436 */         queue.removeLast();phase = VisitPhase.POSTVISIT;
/*      */       }
/*      */       else {
/* 2439 */         mpi = (MPartInfo)parts.getFirst();
/* 2440 */         Element child = addPart(phase, (Element)level.getFirst(), root, mpi, bodies, prefix, maxSize, neuter, excludeCalendarParts, defaultCharset, swallowContentExceptions);
/*      */         
/* 2442 */         if ((phase == VisitPhase.PREVISIT) && (child != null) && (mpi.hasChildren())) {
/* 2443 */           queue.addLast(new Pair(child, new LinkedList(mpi.getChildren())));
/*      */         } else {
/* 2445 */           parts.removeFirst();phase = VisitPhase.PREVISIT;
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static Element addPart(VisitPhase phase, Element parent, Element root, MPartInfo mpi, Set<MPartInfo> bodies, String prefix, int maxSize, boolean neuter, boolean excludeCalendarParts, String defaultCharset, boolean swallowContentExceptions)
/*      */     throws ServiceException
/*      */   {
/* 2454 */     if (phase == VisitPhase.POSTVISIT) {
/* 2455 */       return null;
/*      */     }
/* 2457 */     String ctype = StringUtil.stripControlCharacters(mpi.getContentType());
/*      */     
/* 2459 */     if ((excludeCalendarParts) && ("text/calendar".equalsIgnoreCase(ctype)))
/*      */     {
/*      */       try
/*      */       {
/* 2463 */         ContentType ct = new ContentType(mpi.getMimePart().getContentType());
/* 2464 */         if (ct.getParameter("method") != null) {
/* 2465 */           return null;
/*      */         }
/*      */       }
/*      */       catch (MessagingException e) {}
/*      */     }
/*      */     
/* 2471 */     Element el = parent.addNonUniqueElement("mp");
/* 2472 */     MimePart mp = mpi.getMimePart();
/*      */     
/* 2474 */     String part = mpi.getPartName();
/* 2475 */     part = prefix + ((prefix.isEmpty()) || (part.isEmpty()) ? "" : ".") + part;
/* 2476 */     el.addAttribute("part", part);
/*      */     
/* 2478 */     String fname = Mime.getFilename(mp);
/* 2479 */     if ("xml/x-zimbra-share".equals(ctype))
/*      */     {
/* 2481 */       Element shr = root.addNonUniqueElement("shr");
/*      */       try {
/* 2483 */         addContent(shr, mpi, maxSize, defaultCharset);
/*      */       } catch (IOException e) {
/* 2485 */         if (!swallowContentExceptions) {
/* 2486 */           throw ServiceException.FAILURE("error serializing share XML", e);
/*      */         }
/* 2488 */         LOG.warn("error writing body part", e);
/*      */       }
/*      */       catch (MessagingException e) {
/* 2491 */         if (!swallowContentExceptions) {
/* 2492 */           throw ServiceException.FAILURE("error serializing share XML", e);
/*      */         }
/*      */       }
/* 2495 */     } else if ("xml/x-zimbra-dl-subscription".equals(ctype))
/*      */     {
/* 2497 */       Element dlSubs = root.addNonUniqueElement("dlSubs");
/*      */       try {
/* 2499 */         addContent(dlSubs, mpi, maxSize, defaultCharset);
/*      */       } catch (IOException e) {
/* 2501 */         if (!swallowContentExceptions) {
/* 2502 */           throw ServiceException.FAILURE("error serializing DL subscription", e);
/*      */         }
/* 2504 */         LOG.warn("error writing body part", e);
/*      */       }
/*      */       catch (MessagingException e) {
/* 2507 */         if (!swallowContentExceptions) {
/* 2508 */           throw ServiceException.FAILURE("error serializing DL subscription", e);
/*      */         }
/*      */       }
/* 2511 */     } else if ("text/enriched".equals(ctype))
/*      */     {
/* 2513 */       ctype = "text/html";
/* 2514 */     } else if ((fname != null) && (("application/octet-stream".equals(ctype)) || ("application/ms-tnef".equals(ctype)))) {
/* 2515 */       String guess = MimeDetect.getMimeDetect().detect(fname);
/* 2516 */       if (guess != null) {
/* 2517 */         ctype = guess;
/*      */       }
/*      */     }
/* 2520 */     el.addAttribute("ct", ctype);
/*      */     
/* 2522 */     if (mpi.isMultipart()) {
/* 2523 */       return el;
/*      */     }
/*      */     
/*      */     try
/*      */     {
/* 2528 */       el.addAttribute("s", Mime.getSize(mp));
/*      */     } catch (Exception e) {
/* 2530 */       ZimbraLog.mailbox.warn("Unable to determine MIME part size: %s", new Object[] { e.getMessage() });
/*      */     }
/*      */     
/*      */     try
/*      */     {
/* 2535 */       String disp = mp.getHeader("Content-Disposition", null);
/* 2536 */       if (disp != null) {
/* 2537 */         ContentDisposition cdisp = new ContentDisposition(MimeUtility.decodeText(disp));
/* 2538 */         el.addAttribute("cd", StringUtil.stripControlCharacters(cdisp.getDisposition()));
/*      */       }
/*      */     }
/*      */     catch (MessagingException e) {}catch (UnsupportedEncodingException e) {}
/*      */     
/*      */ 
/*      */     try
/*      */     {
/* 2546 */       if ((fname == null) && ("message/rfc822".equals(ctype)))
/*      */       {
/* 2548 */         Object content = Mime.getMessageContent(mp);
/* 2549 */         if ((content instanceof MimeMessage)) {
/* 2550 */           fname = Mime.getSubject((MimeMessage)content);
/*      */         }
/*      */       }
/* 2553 */       if (!Strings.isNullOrEmpty(fname)) {
/* 2554 */         el.addAttribute("filename", StringUtil.stripControlCharacters(fname));
/*      */       }
/*      */     }
/*      */     catch (MessagingException me) {}catch (IOException ioe) {}
/*      */     
/*      */ 
/*      */ 
/* 2561 */     String cid = mpi.getContentID();
/* 2562 */     if (cid != null) {
/* 2563 */       el.addAttribute("ci", StringUtil.stripControlCharacters(cid));
/*      */     }
/*      */     try
/*      */     {
/* 2567 */       String cl = mp.getHeader("Content-Location", null);
/* 2568 */       if (cl != null) {
/* 2569 */         el.addAttribute("cl", StringUtil.stripControlCharacters(cl));
/*      */       }
/*      */     }
/*      */     catch (MessagingException e) {}
/*      */     
/*      */ 
/*      */ 
/* 2576 */     if ((bodies == null) || (bodies.contains(mpi))) {
/* 2577 */       if (bodies != null) {
/* 2578 */         el.addAttribute("body", true);
/*      */       }
/*      */       try
/*      */       {
/* 2582 */         addContent(el, mpi, maxSize, neuter, defaultCharset);
/*      */       } catch (IOException e) {
/* 2584 */         if (!swallowContentExceptions) {
/* 2585 */           throw ServiceException.FAILURE("error serializing part content", e);
/*      */         }
/* 2587 */         LOG.warn("error writing body part", e);
/*      */       }
/*      */       catch (MessagingException me) {
/* 2590 */         if (!swallowContentExceptions) {
/* 2591 */           throw ServiceException.FAILURE("error serializing part content", me);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/* 2596 */     return el;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static void addContent(Element elt, MPartInfo mpi, int maxSize, String defaultCharset)
/*      */     throws IOException, MessagingException
/*      */   {
/* 2611 */     addContent(elt, mpi, maxSize, true, defaultCharset);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset)
/*      */     throws IOException, MessagingException
/*      */   {
/* 2630 */     String ctype = mpi.getContentType();
/* 2631 */     if ((!ctype.matches("text/.*")) && (!ctype.matches("xml/.*"))) {
/* 2632 */       return;
/*      */     }
/* 2634 */     MimePart mp = mpi.getMimePart();
/* 2635 */     Mime.repairTransferEncoding(mp);
/*      */     
/* 2637 */     String data = null;
/*      */     try {
/* 2639 */       if (maxSize <= 0) {
/* 2640 */         maxSize = (int)Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
/*      */       } else {
/* 2642 */         maxSize = Math.min(maxSize, (int)Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
/*      */       }
/*      */     } catch (ServiceException e) {
/* 2645 */       ZimbraLog.soap.warn("Unable to determine max content size", e);
/*      */     }
/*      */     
/* 2648 */     boolean wasTruncated = false;
/* 2649 */     if (ctype.equals("text/html")) {
/* 2650 */       String charset = mpi.getContentTypeParameter("charset");
/* 2651 */       InputStream stream = null;
/* 2652 */       StringWriter sw = new StringWriter();
/* 2653 */       TruncatingWriter tw = null;
/* 2654 */       Writer out = sw;
/* 2655 */       if (maxSize > 0) {
/* 2656 */         tw = new TruncatingWriter(sw, maxSize + 1);
/* 2657 */         out = tw;
/*      */       }
/* 2659 */       Reader reader = null;
/*      */       try
/*      */       {
/* 2662 */         stream = mp.getInputStream();
/* 2663 */         if ((charset != null) && (!charset.trim().isEmpty()))
/*      */         {
/* 2665 */           reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
/* 2666 */           BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
/* 2667 */           defanger.defang(reader, neuter, out);
/* 2668 */           data = sw.toString();
/*      */         } else {
/* 2670 */           String cte = mp.getEncoding();
/* 2671 */           if ((cte != null) && (!cte.trim().toLowerCase().equals("7bit"))) {
/*      */             try {
/* 2673 */               DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
/* 2674 */               data = sw.toString();
/*      */             }
/*      */             catch (IOException e) {}
/*      */           }
/* 2678 */           if (data == null) {
/* 2679 */             reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
/* 2680 */             DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
/* 2681 */             data = sw.toString();
/*      */           }
/*      */         }
/*      */       } finally {
/* 2685 */         if (tw != null) {
/* 2686 */           wasTruncated = tw.wasTruncated();
/*      */         }
/* 2688 */         ByteUtil.closeStream(stream);
/* 2689 */         Closeables.closeQuietly(reader);
/*      */       }
/* 2691 */     } else if (ctype.equals("text/enriched"))
/*      */     {
/*      */ 
/*      */ 
/* 2695 */       InputStream stream = mp.getInputStream();
/* 2696 */       Reader reader = null;
/*      */       try {
/* 2698 */         reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
/* 2699 */         int maxChars = maxSize > 0 ? maxSize + 1 : -1;
/* 2700 */         String enriched = ByteUtil.getContent(reader, maxChars, false);
/* 2701 */         if (enriched.length() == maxChars)
/*      */         {
/*      */ 
/*      */ 
/* 2705 */           wasTruncated = true;
/*      */         }
/* 2707 */         data = TextEnrichedHandler.convertToHTML(enriched);
/*      */       } finally {
/* 2709 */         ByteUtil.closeStream(stream);
/* 2710 */         Closeables.closeQuietly(reader);
/*      */       }
/*      */     } else {
/* 2713 */       InputStream stream = mp.getInputStream();
/* 2714 */       Reader reader = null;
/*      */       try {
/* 2716 */         reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
/* 2717 */         int maxChars = maxSize > 0 ? maxSize + 1 : -1;
/* 2718 */         data = ByteUtil.getContent(reader, maxChars, false);
/* 2719 */         if (data.length() == maxChars) {
/* 2720 */           wasTruncated = true;
/*      */         }
/*      */       } finally {
/* 2723 */         ByteUtil.closeStream(stream);
/* 2724 */         Closeables.closeQuietly(reader);
/*      */       }
/*      */     }
/*      */     
/* 2728 */     if (data != null) {
/* 2729 */       data = StringUtil.stripControlCharacters(data);
/* 2730 */       if (wasTruncated) {
/* 2731 */         elt.addAttribute("truncated", true);
/* 2732 */         if (data.length() > maxSize) {
/* 2733 */           data = data.substring(0, maxSize);
/*      */         }
/*      */       }
/* 2736 */       elt.addAttribute("content", data, Element.Disposition.CONTENT);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public static enum EmailType
/*      */   {
/* 2743 */     NONE(null),  FROM("f"),  TO("t"),  CC("c"),  BCC("b"),  REPLY_TO("r"),  SENDER("s"),  READ_RECEIPT("n"),  RESENT_FROM("rf");
/*      */     
/*      */     private final String rep;
/*      */     
/* 2747 */     private EmailType(String c) { this.rep = c; }
/*      */     
/*      */ 
/*      */     public String toString()
/*      */     {
/* 2752 */       return this.rep;
/*      */     }
/*      */   }
/*      */   
/*      */   private static void addEmails(Element m, InternetAddress[] recipients, EmailType emailType) {
/* 2757 */     for (InternetAddress rcpt : recipients) {
/* 2758 */       encodeEmail(m, rcpt, emailType);
/*      */     }
/*      */   }
/*      */   
/*      */   public static Element encodeEmail(Element parent, InternetAddress ia, EmailType type) {
/* 2763 */     return encodeEmail(parent, new ParsedAddress(ia).parse(), type);
/*      */   }
/*      */   
/*      */   public static Element encodeEmail(Element parent, String addr, EmailType type) {
/* 2767 */     return encodeEmail(parent, new ParsedAddress(addr).parse(), type);
/*      */   }
/*      */   
/*      */   public static Element encodeEmail(Element parent, ParsedAddress pa, EmailType type) {
/* 2771 */     Element el = parent.addElement("e");
/* 2772 */     if (!StringUtil.isNullOrEmpty(pa.emailPart)) {
/* 2773 */       pa.emailPart = ZInternetHeader.decode(pa.emailPart);
/*      */     }
/* 2775 */     el.addAttribute("a", IDNUtil.toUnicode(pa.emailPart));
/* 2776 */     if (!StringUtil.isNullOrEmpty(pa.firstName)) {
/* 2777 */       pa.firstName = ZInternetHeader.decode(pa.firstName);
/*      */     }
/* 2779 */     el.addAttribute("d", pa.firstName);
/* 2780 */     if (!StringUtil.isNullOrEmpty(pa.personalPart)) {
/* 2781 */       pa.personalPart = ZInternetHeader.decode(pa.personalPart);
/*      */     }
/* 2783 */     el.addAttribute("p", pa.personalPart);
/* 2784 */     el.addAttribute("t", type.toString());
/* 2785 */     return el;
/*      */   }
/*      */   
/*      */   public static Element encodeWiki(Element parent, ItemIdFormatter ifmt, OperationContext octxt, WikiItem wiki) throws ServiceException {
/* 2789 */     return encodeWiki(parent, ifmt, octxt, wiki, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeWiki(Element parent, ItemIdFormatter ifmt, OperationContext octxt, WikiItem wiki, int fields) throws ServiceException
/*      */   {
/* 2794 */     Element elem = parent.addElement("w");
/* 2795 */     encodeDocumentCommon(elem, ifmt, octxt, wiki, fields);
/* 2796 */     return elem;
/*      */   }
/*      */   
/*      */   public static Element encodeDocument(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Document doc) throws ServiceException {
/* 2800 */     return encodeDocument(parent, ifmt, octxt, doc, -1);
/*      */   }
/*      */   
/*      */   public static Element encodeDocument(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Document doc, int fields) throws ServiceException
/*      */   {
/* 2805 */     Element el = parent.addElement("doc");
/* 2806 */     encodeDocumentCommon(el, ifmt, octxt, doc, fields);
/* 2807 */     if (needToOutput(fields, 8388608)) {
/* 2808 */       String lockOwner = doc.getLockOwner();
/* 2809 */       if (lockOwner == null) {
/* 2810 */         el.addAttribute("loid", "");
/*      */       }
/*      */       else {
/*      */         try {
/* 2814 */           Account a = Provisioning.getInstance().getAccountById(lockOwner);
/* 2815 */           if (a != null) {
/* 2816 */             el.addAttribute("loe", a.getName());
/*      */           } else {
/* 2818 */             ZimbraLog.soap.warn("lock owner not found: %s", new Object[] { lockOwner });
/*      */           }
/*      */         } catch (ServiceException e) {
/* 2821 */           ZimbraLog.soap.warn("can't lookup lock owner", e);
/*      */         }
/* 2823 */         el.addAttribute("loid", lockOwner);
/* 2824 */         el.addAttribute("lt", doc.getLockTimestamp());
/*      */       }
/*      */     }
/* 2827 */     return el;
/*      */   }
/*      */   
/*      */   public static Element encodeDocumentCommon(Element m, ItemIdFormatter ifmt, OperationContext octxt, Document doc, int fields) throws ServiceException
/*      */   {
/* 2832 */     m.addAttribute("id", ifmt.formatItemId(doc));
/* 2833 */     m.addAttribute("uuid", doc.getUuid());
/* 2834 */     if (needToOutput(fields, 4096)) {
/* 2835 */       m.addAttribute("name", doc.getName());
/*      */     }
/* 2837 */     if (needToOutput(fields, 16)) {
/* 2838 */       m.addAttribute("s", doc.getSize());
/*      */     }
/* 2840 */     if (needToOutput(fields, 32)) {
/* 2841 */       m.addAttribute("d", doc.getDate());
/*      */     }
/* 2843 */     if (needToOutput(fields, 256)) {
/* 2844 */       m.addAttribute("l", ifmt.formatItemId(new ItemId(doc.getMailbox().getAccountId(), doc.getFolderId())));
/*      */       
/* 2846 */       m.addAttribute("luuid", doc.getFolderUuid());
/*      */     }
/* 2848 */     if (needToOutput(fields, 4194304)) {
/* 2849 */       m.addAttribute("ms", doc.getModifiedSequence());
/* 2850 */       m.addAttribute("mdver", doc.getMetadataVersion());
/* 2851 */       m.addAttribute("md", doc.getChangeDate() / 1000L);
/* 2852 */       m.addAttribute("rev", doc.getSavedSequence());
/*      */     }
/* 2854 */     recordItemTags(m, doc, octxt, fields | 0x4);
/* 2855 */     if (needToOutput(fields, 524288)) {
/* 2856 */       encodeAllCustomMetadata(m, doc, fields);
/* 2857 */       String description = doc.getDescription();
/* 2858 */       if (!Strings.isNullOrEmpty(description)) {
/* 2859 */         m.addAttribute("desc", description);
/*      */       }
/* 2861 */       m.addAttribute("ct", doc.getContentType());
/* 2862 */       m.addAttribute("descEnabled", doc.isDescriptionEnabled());
/*      */     }
/*      */     
/* 2865 */     if ((needToOutput(fields, 65536)) || (needToOutput(fields, 4096))) {
/*      */       try {
/* 2867 */         m.addAttribute("ver", doc.getVersion());
/* 2868 */         m.addAttribute("leb", doc.getCreator());
/* 2869 */         String fragment = doc.getFragment();
/* 2870 */         if (!Strings.isNullOrEmpty(fragment)) {
/* 2871 */           m.addAttribute("fr", fragment, Element.Disposition.CONTENT);
/*      */         }
/* 2873 */         Document revision = null;
/* 2874 */         int v = 1;
/* 2875 */         while ((revision == null) && (v <= doc.getVersion())) {
/* 2876 */           revision = (Document)doc.getMailbox().getItemRevision(octxt, doc.getId(), doc.getType(), v++, doc.inDumpster());
/*      */         }
/* 2878 */         if (revision != null) {
/* 2879 */           m.addAttribute("cr", revision.getCreator());
/* 2880 */           m.addAttribute("cd", revision.getDate());
/*      */         }
/*      */       } catch (Exception e) {
/* 2883 */         LOG.warn("ignoring exception while fetching revision for document %s", doc.getSubject(), e);
/*      */       }
/*      */     }
/*      */     
/*      */ 
/* 2888 */     if ((needToOutput(fields, 2097152)) && (
/* 2889 */       (fields != -4194305) || (doc.isTagged(Flag.FlagInfo.NO_INHERIT)))) {
/* 2890 */       encodeACL(octxt, m, doc.getEffectiveACL(), false);
/*      */     }
/*      */     
/* 2893 */     for (ToXMLExtension ext : extensions) {
/* 2894 */       ext.encodeDocumentAdditionalAttribute(m, ifmt, octxt, doc, fields);
/*      */     }
/* 2896 */     return m;
/*      */   }
/*      */   
/*      */   public static Element encodeDataSource(Element parent, DataSource ds) {
/* 2900 */     Element m = parent.addElement(getDsType(ds));
/* 2901 */     m.addAttribute("id", ds.getId());
/* 2902 */     m.addAttribute("name", ds.getName());
/* 2903 */     m.addAttribute("l", ds.getFolderId());
/* 2904 */     m.addAttribute("isEnabled", ds.isEnabled());
/* 2905 */     m.addAttribute("importOnly", ds.isImportOnly());
/*      */     
/* 2907 */     if (ds.getType() == DataSourceType.pop3) {
/* 2908 */       m.addAttribute("leaveOnServer", ds.leaveOnServer());
/*      */     }
/* 2910 */     if (ds.getHost() != null) {
/* 2911 */       m.addAttribute("host", ds.getHost());
/*      */     }
/* 2913 */     if (ds.getPort() != null) {
/* 2914 */       m.addAttribute("port", ds.getPort());
/*      */     }
/* 2916 */     if (ds.getConnectionType() != null) {
/* 2917 */       m.addAttribute("connectionType", ds.getConnectionType().name());
/*      */     }
/* 2919 */     if (ds.getUsername() != null) {
/* 2920 */       m.addAttribute("username", ds.getUsername());
/*      */     }
/*      */     try {
/* 2923 */       if (ds.getPollingInterval() > 0L) {
/* 2924 */         m.addAttribute("pollingInterval", ds.getPollingInterval());
/*      */       }
/*      */     } catch (ServiceException e) {
/* 2927 */       LOG.warn("Unable to get polling interval from %s", ds, e);
/*      */     }
/*      */     
/* 2930 */     m.addAttribute("emailAddress", ds.getEmailAddress());
/* 2931 */     m.addAttribute("useAddressForForwardReply", ds.useAddressForForwardReply());
/* 2932 */     m.addAttribute("defaultSignature", ds.getDefaultSignature());
/* 2933 */     m.addAttribute("forwardReplySignature", ds.getForwardReplySignature());
/* 2934 */     m.addAttribute("fromDisplay", ds.getFromDisplay());
/* 2935 */     m.addAttribute("replyToAddress", ds.getReplyToAddress());
/* 2936 */     m.addAttribute("replyToDisplay", ds.getReplyToDisplay());
/*      */     
/* 2938 */     Date date = ds.getGeneralizedTimeAttr("zimbraDataSourceFailingSince", null);
/* 2939 */     if (date != null) {
/* 2940 */       m.addAttribute("failingSince", date.getTime() / 1000L);
/*      */     }
/*      */     
/* 2943 */     String lastError = ds.getAttr("zimbraDataSourceLastError");
/* 2944 */     if (lastError != null) {
/* 2945 */       m.addElement("lastError").setText(lastError);
/*      */     }
/* 2947 */     return m;
/*      */   }
/*      */   
/*      */   private static String getDsType(DataSource ds) {
/* 2951 */     switch (ds.getType()) {
/*      */     case imap: 
/* 2953 */       return "imap";
/*      */     case pop3: 
/* 2955 */       return "pop3";
/*      */     case caldav: 
/* 2957 */       return "caldav";
/*      */     case yab: 
/* 2959 */       return "yab";
/*      */     case rss: 
/* 2961 */       return "rss";
/*      */     case gal: 
/* 2963 */       return "gal";
/*      */     case cal: 
/* 2965 */       return "cal";
/*      */     }
/* 2967 */     return "unknown";
/*      */   }
/*      */   
/*      */   private static void setCalendarItemType(Element elem, MailItem.Type type)
/*      */   {
/* 2972 */     elem.addAttribute("type", type == MailItem.Type.APPOINTMENT ? "appt" : "task");
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   private static long getNextAlarmTime(CalendarItem calItem)
/*      */   {
/* 2979 */     CalendarItem.AlarmData alarmData = calItem.getAlarmData();
/* 2980 */     if (alarmData == null) {
/* 2981 */       return Long.MAX_VALUE;
/*      */     }
/* 2983 */     return alarmData.getNextAt();
/*      */   }
/*      */   
/*      */   public static void encodeAlarmTimes(Element elem, CalendarItem calItem) {
/* 2987 */     long nextAlarm = getNextAlarmTime(calItem);
/* 2988 */     if (nextAlarm < Long.MAX_VALUE) {
/* 2989 */       elem.addAttribute("nextAlarm", nextAlarm);
/*      */     }
/*      */   }
/*      */   
/*      */   public static AlarmDataInfo alarmDataToJaxb(CalendarItem calItem, CalendarItem.AlarmData alarmData) {
/* 2994 */     AlarmDataInfo alarm = new AlarmDataInfo();
/* 2995 */     long nextAlarm = getNextAlarmTime(calItem);
/* 2996 */     if (nextAlarm < Long.MAX_VALUE) {
/* 2997 */       alarm.setNextAlarm(Long.valueOf(nextAlarm));
/*      */     }
/* 2999 */     long alarmInstStart = alarmData.getNextInstanceStart();
/* 3000 */     if (alarmInstStart != 0L) {
/* 3001 */       alarm.setAlarmInstanceStart(Long.valueOf(alarmInstStart));
/*      */     }
/* 3003 */     int alarmInvId = alarmData.getInvId();
/* 3004 */     int alarmCompNum = alarmData.getCompNum();
/* 3005 */     Invite alarmInv = calItem.getInvite(alarmInvId, alarmCompNum);
/* 3006 */     if (alarmInv != null)
/*      */     {
/*      */ 
/*      */ 
/* 3010 */       alarm.setName(alarmInv.getName());
/* 3011 */       alarm.setLocation(alarmInv.getLocation());
/* 3012 */       alarm.setInvId(Integer.valueOf(alarmInvId));
/* 3013 */       alarm.setComponentNum(Integer.valueOf(alarmCompNum));
/*      */     }
/* 3015 */     Alarm alarmObj = alarmData.getAlarm();
/* 3016 */     if (alarmObj != null) {
/* 3017 */       alarm.setAlarm(alarmObj.toJaxb());
/*      */     }
/* 3019 */     return alarm;
/*      */   }
/*      */   
/*      */   public static Element encodeAlarmData(Element parent, CalendarItem calItem, CalendarItem.AlarmData alarmData) {
/* 3023 */     Element alarmElem = parent.addElement("alarmData");
/* 3024 */     encodeAlarmTimes(alarmElem, calItem);
/*      */     
/* 3026 */     long alarmInstStart = alarmData.getNextInstanceStart();
/* 3027 */     if (alarmInstStart != 0L) {
/* 3028 */       alarmElem.addAttribute("alarmInstStart", alarmInstStart);
/*      */     }
/* 3030 */     int alarmInvId = alarmData.getInvId();
/* 3031 */     int alarmCompNum = alarmData.getCompNum();
/* 3032 */     Invite alarmInv = calItem.getInvite(alarmInvId, alarmCompNum);
/* 3033 */     if (alarmInv != null)
/*      */     {
/*      */ 
/*      */ 
/* 3037 */       alarmElem.addAttribute("name", alarmInv.getName());
/* 3038 */       alarmElem.addAttribute("loc", alarmInv.getLocation());
/* 3039 */       alarmElem.addAttribute("invId", alarmInvId);
/* 3040 */       alarmElem.addAttribute("compNum", alarmCompNum);
/*      */     }
/* 3042 */     Alarm alarmObj = alarmData.getAlarm();
/* 3043 */     if (alarmObj != null) {
/* 3044 */       alarmObj.toXml(alarmElem);
/*      */     }
/* 3046 */     return alarmElem;
/*      */   }
/*      */   
/*      */   public static Element encodeFreeBusy(Element parent, FreeBusy fb) {
/* 3050 */     Element resp = parent.addElement("usr");
/* 3051 */     resp.addAttribute("id", fb.getName());
/* 3052 */     for (Iterator<FreeBusy.Interval> iter = fb.iterator(); iter.hasNext();) {
/* 3053 */       FreeBusy.Interval cur = (FreeBusy.Interval)iter.next();
/* 3054 */       String status = cur.getStatus();
/*      */       Element elt;
/* 3056 */       Element elt; if (status.equals("F")) {
/* 3057 */         elt = resp.addElement("f"); } else { Element elt;
/* 3058 */         if (status.equals("B")) {
/* 3059 */           elt = resp.addElement("b"); } else { Element elt;
/* 3060 */           if (status.equals("T")) {
/* 3061 */             elt = resp.addElement("t"); } else { Element elt;
/* 3062 */             if (status.equals("O")) {
/* 3063 */               elt = resp.addElement("u"); } else { Element elt;
/* 3064 */               if (status.equals("N")) {
/* 3065 */                 elt = resp.addElement("n");
/*      */               } else {
/* 3067 */                 if (!$assertionsDisabled) throw new AssertionError();
/* 3068 */                 elt = null;
/*      */               }
/*      */             } } } }
/* 3071 */       if (elt != null) {
/* 3072 */         elt.addAttribute("s", cur.getStart());
/* 3073 */         elt.addAttribute("e", cur.getEnd());
/*      */       }
/*      */     }
/*      */     
/* 3077 */     return resp;
/*      */   }
/*      */   
/*      */   private static Element encodeRecurId(Element parent, RecurId recurId, boolean allDay) {
/* 3081 */     ParsedDateTime ridDt = recurId.getDt();
/* 3082 */     Element ridElem = parent.addElement("exceptId");
/* 3083 */     ridElem.addAttribute("d", ridDt.getDateTimePartString(false));
/* 3084 */     if (!allDay) {
/* 3085 */       ridElem.addAttribute("tz", ridDt.getTZName());
/*      */     }
/* 3087 */     int rangeType = recurId.getRange();
/* 3088 */     if (rangeType != RecurId.RANGE_NONE) {
/* 3089 */       ridElem.addAttribute("rangeType", rangeType);
/*      */     }
/* 3091 */     return ridElem;
/*      */   }
/*      */   
/*      */   private static Element encodeDtStart(Element parent, ParsedDateTime dtStart, boolean allDay, boolean forceUtc) {
/* 3095 */     if (forceUtc) {
/* 3096 */       dtStart = (ParsedDateTime)dtStart.clone();
/* 3097 */       dtStart.toUTC();
/*      */     }
/*      */     
/* 3100 */     if ((allDay) && (dtStart.hasTime()))
/*      */     {
/* 3102 */       dtStart = (ParsedDateTime)dtStart.clone();
/* 3103 */       dtStart.setHasTime(false);
/* 3104 */     } else if ((!allDay) && (!dtStart.hasTime()))
/*      */     {
/* 3106 */       allDay = true;
/*      */     }
/* 3108 */     Element dtStartElem = parent.addElement("s");
/* 3109 */     dtStartElem.addAttribute("d", dtStart.getDateTimePartString(false));
/* 3110 */     if (!allDay) {
/* 3111 */       String tzName = dtStart.getTZName();
/* 3112 */       if (tzName != null) {
/* 3113 */         dtStartElem.addAttribute("tz", tzName);
/*      */       }
/* 3115 */       dtStartElem.addAttribute("u", dtStart.getUtcTime());
/*      */     }
/* 3117 */     return dtStartElem;
/*      */   }
/*      */   
/*      */   private static Element encodeDtEnd(Element parent, ParsedDateTime dtEnd, boolean allDay, boolean isTodo, boolean forceUtc) {
/* 3121 */     if (forceUtc) {
/* 3122 */       dtEnd = (ParsedDateTime)dtEnd.clone();
/* 3123 */       dtEnd.toUTC();
/*      */     }
/*      */     
/* 3126 */     if ((allDay) && (dtEnd.hasTime()))
/*      */     {
/* 3128 */       dtEnd = (ParsedDateTime)dtEnd.clone();
/* 3129 */       dtEnd.setHasTime(false);
/* 3130 */     } else if ((!allDay) && (!dtEnd.hasTime()))
/*      */     {
/* 3132 */       allDay = true;
/*      */     }
/* 3134 */     Element dtEndElem = parent.addElement("e");
/* 3135 */     if (!allDay) {
/* 3136 */       String tzName = dtEnd.getTZName();
/* 3137 */       if (tzName != null) {
/* 3138 */         dtEndElem.addAttribute("tz", tzName);
/*      */       }
/* 3140 */       dtEndElem.addAttribute("u", dtEnd.getUtcTime());
/*      */     }
/* 3142 */     else if (!isTodo)
/*      */     {
/*      */ 
/* 3145 */       dtEnd = dtEnd.add(ParsedDuration.NEGATIVE_ONE_DAY);
/*      */     }
/*      */     
/* 3148 */     dtEndElem.addAttribute("d", dtEnd.getDateTimePartString(false));
/* 3149 */     return dtEndElem;
/*      */   }
/*      */   
/*      */   public static void encodeCalendarItemRecur(Element parent, CalendarItem calItem) {
/* 3153 */     TimeZoneMap tzmap = calItem.getTimeZoneMap();
/* 3154 */     encodeTimeZoneMap(parent, tzmap);
/* 3155 */     Invite[] invites = calItem.getInvites();
/* 3156 */     for (Invite inv : invites) { String elemName;
/*      */       String elemName;
/* 3158 */       if (inv.isCancel()) {
/* 3159 */         elemName = "cancel"; } else { String elemName;
/* 3160 */         if (inv.hasRecurId()) {
/* 3161 */           elemName = "except";
/*      */         } else
/* 3163 */           elemName = "comp";
/*      */       }
/* 3165 */       Element compElem = parent.addElement(elemName);
/* 3166 */       boolean allDay = inv.isAllDayEvent();
/*      */       
/* 3168 */       if (inv.hasRecurId())
/* 3169 */         encodeRecurId(compElem, inv.getRecurId(), allDay);
/* 3170 */       if (!inv.isCancel())
/*      */       {
/* 3172 */         ParsedDateTime dtStart = inv.getStartTime();
/* 3173 */         if (dtStart != null) {
/* 3174 */           encodeDtStart(compElem, dtStart, allDay, false);
/*      */         }
/* 3176 */         ParsedDateTime dtEnd = inv.getEndTime();
/* 3177 */         if (dtEnd != null) {
/* 3178 */           encodeDtEnd(compElem, dtEnd, allDay, inv.isTodo(), false);
/*      */         } else {
/* 3180 */           ParsedDuration dur = inv.getDuration();
/* 3181 */           if (dur != null) {
/* 3182 */             dur.toXml(compElem);
/*      */           }
/*      */         }
/*      */         
/* 3186 */         Recurrence.IRecurrence recurrence = inv.getRecurrence();
/* 3187 */         if (recurrence != null) {
/* 3188 */           Element recurElem = compElem.addElement("recur");
/* 3189 */           recurrence.toXml(recurElem);
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static Element encodeGalContact(Element response, GalContact contact) {
/* 3196 */     return encodeGalContact(response, contact, null);
/*      */   }
/*      */   
/*      */   public static Element encodeGalContact(Element response, GalContact contact, Collection<String> returnAttrs)
/*      */   {
/* 3201 */     Element cn = response.addElement("cn");
/* 3202 */     cn.addAttribute("id", contact.getId());
/* 3203 */     Map<String, Object> attrs = contact.getAttrs();
/* 3204 */     for (Map.Entry<String, Object> entry : attrs.entrySet()) {
/* 3205 */       String key = (String)entry.getKey();
/* 3206 */       if ((returnAttrs == null) || (returnAttrs.contains(key))) {
/* 3207 */         Object value = entry.getValue();
/* 3208 */         if ((value instanceof String[])) {
/* 3209 */           String[] sa = (String[])value;
/* 3210 */           for (int i = 0; i < sa.length; i++)
/* 3211 */             cn.addKeyValuePair(key, sa[i], "a", "n");
/*      */         } else {
/* 3213 */           cn.addKeyValuePair(key, (String)value, "a", "n");
/*      */         }
/*      */       }
/*      */     }
/* 3217 */     return cn;
/*      */   }
/*      */   
/*      */   private static void encodeAddrsWithGroupInfo(Element eMsg, Account requestedAcct, Account authedAcct) {
/* 3221 */     encodeAddrsWithGroupInfo(eMsg, "e", requestedAcct, authedAcct);
/* 3222 */     Element eInvite = eMsg.getOptionalElement("inv");
/* 3223 */     if (eInvite != null) {
/* 3224 */       Element eComp = eInvite.getOptionalElement("comp");
/* 3225 */       if (eComp != null) {
/* 3226 */         encodeAddrsWithGroupInfo(eComp, "at", requestedAcct, authedAcct);
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private static void encodeAddrsWithGroupInfo(Element eParent, String emailElem, Account requestedAcct, Account authedAcct) {
/*      */     GalGroupInfoProvider groupInfoProvider;
/* 3233 */     if ((requestedAcct.isFeatureGalEnabled()) && (requestedAcct.isFeatureGalAutoCompleteEnabled()) && (requestedAcct.isPrefGalAutoCompleteEnabled()))
/*      */     {
/*      */ 
/* 3236 */       groupInfoProvider = GalGroupInfoProvider.getInstance();
/*      */       
/* 3238 */       for (Element eEmail : eParent.listElements(emailElem)) {
/* 3239 */         String addr = eEmail.getAttribute("a", null);
/* 3240 */         if (addr != null)
/*      */         {
/* 3242 */           if ((!addr.equalsIgnoreCase(requestedAcct.getName())) && (!addr.equalsIgnoreCase(authedAcct.getName())))
/*      */           {
/*      */ 
/* 3245 */             GalGroup.GroupInfo groupInfo = groupInfoProvider.getGroupInfo(addr, true, requestedAcct, authedAcct);
/* 3246 */             if (GalGroup.GroupInfo.IS_GROUP == groupInfo) {
/* 3247 */               eEmail.addAttribute("isGroup", true);
/* 3248 */               eEmail.addAttribute("exp", false);
/* 3249 */             } else if (GalGroup.GroupInfo.CAN_EXPAND == groupInfo) {
/* 3250 */               eEmail.addAttribute("isGroup", true);
/* 3251 */               eEmail.addAttribute("exp", true);
/*      */             }
/*      */           } }
/*      */       }
/* 3255 */     } else if (ZimbraLog.gal.isTraceEnabled()) {
/* 3256 */       ZimbraLog.gal.trace("group info bypassed; account [%s] does not have required attributes isFeatureGalEnabled [%s] isFeatureGalAutoCompleteEnabled [%s] isPrefGalAutoCompleteEnabled [%s]", new Object[] { requestedAcct, Boolean.valueOf(requestedAcct.isFeatureGalEnabled()), Boolean.valueOf(requestedAcct.isFeatureGalAutoCompleteEnabled()), Boolean.valueOf(requestedAcct.isPrefGalAutoCompleteEnabled()) });
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public static Element encodeComment(Element response, ItemIdFormatter ifmt, OperationContext octxt, Comment comment)
/*      */     throws ServiceException
/*      */   {
/* 3264 */     return encodeComment(response, ifmt, octxt, comment, -4194305);
/*      */   }
/*      */   
/*      */   public static Element encodeComment(Element response, ItemIdFormatter ifmt, OperationContext octxt, Comment comment, int fields) throws ServiceException
/*      */   {
/* 3269 */     Element c = response.addElement("comment");
/* 3270 */     if (needToOutput(fields, 512)) {
/* 3271 */       c.addAttribute("parentId", ifmt.formatItemId(comment.getParentId()));
/*      */     }
/* 3273 */     if (needToOutput(fields, 64)) {
/* 3274 */       c.setText(comment.getText());
/*      */     }
/* 3276 */     c.addAttribute("id", ifmt.formatItemId(comment));
/* 3277 */     c.addAttribute("uuid", comment.getUuid());
/*      */     try {
/* 3279 */       Account a = comment.getCreatorAccount();
/* 3280 */       if (a != null) {
/* 3281 */         c.addAttribute("email", a.getName());
/*      */       }
/*      */     }
/*      */     catch (ServiceException e) {}
/* 3285 */     recordItemTags(c, comment, octxt, fields);
/* 3286 */     encodeColor(c, comment, fields);
/* 3287 */     if (needToOutput(fields, 32)) {
/* 3288 */       c.addAttribute("d", comment.getDate());
/*      */     }
/* 3290 */     if (needToOutput(fields, 524288)) {
/* 3291 */       encodeAllCustomMetadata(c, comment, fields);
/*      */     }
/* 3293 */     return c;
/*      */   }
/*      */   
/*      */   public static Element encodeLink(Element response, ItemIdFormatter ifmt, Link link, int fields) {
/* 3297 */     Element el = response.addElement("lk");
/* 3298 */     el.addAttribute("id", ifmt.formatItemId(link));
/* 3299 */     el.addAttribute("uuid", link.getUuid());
/*      */     
/* 3301 */     if (needToOutput(fields, 4096)) {
/* 3302 */       String name = link.getName();
/* 3303 */       if (!Strings.isNullOrEmpty(name)) {
/* 3304 */         el.addAttribute("name", name);
/*      */       }
/*      */     }
/* 3307 */     if (needToOutput(fields, 65536)) {
/* 3308 */       el.addAttribute("zid", link.getOwnerId());
/* 3309 */       el.addAttribute("rid", link.getRemoteId());
/* 3310 */       NamedEntry nentry = FolderAction.lookupGranteeByZimbraId(link.getOwnerId(), (byte)1);
/* 3311 */       el.addAttribute("owner", nentry == null ? null : nentry.getName());
/*      */     }
/* 3313 */     return el;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/* 3321 */   private static Set<ToXMLExtension> extensions = new HashSet();
/*      */   
/*      */   public static void addExtension(ToXMLExtension e) {
/* 3324 */     extensions.add(e);
/*      */   }
/*      */   
/*      */   public static abstract interface ToXMLExtension
/*      */   {
/*      */     public abstract Element encodeDocumentAdditionalAttribute(Element paramElement, ItemIdFormatter paramItemIdFormatter, OperationContext paramOperationContext, Document paramDocument, int paramInt);
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/ToXML.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */